Ksbs 的设计与演化


#1

很久很久以前, 我学习了一门叫 C++ 的语言。那个时候我在写一个叫 Emacs 的软件的变种。源于对 C 和 C++ 的厌恶, 我把我的厌恶都发泄到了用户身上。 如果用户做错了什么,程序会侮辱他,把他叫做火鸡,并把屏幕填满垃圾。

后来 这个 Emacs 版本没人用了,我于是去了 DIM 公司混饭吃。 在那里, 我遇到了同样一群讨厌 C++ 的人 。C++是如此的难用,我们决定设计一个更简单的 C++。

我对 C++ 的第一个讨厌的地方就是 他的内存管理。 太讨厌了! 我得不停的写 new delete, 还得操心 new [] 和 delete [] 的区别。 还得时刻关注一个对象的生命周期,一不小心忘记了就要内存泄漏了。

编写 Emacs 的经历让我很快的想到了 lisp 语言, lisp 语言里带有一个垃圾收集器, 于是,我就把垃圾收集器带到了我的语言里。

因为有了垃圾收集,程序就非常简单咯~ 在也不用操心内存管理了。

等等, 用户要是把指针存到 int 里, 然后再 cast 出来咋办? 垃圾收集没办法对付这种情况啊! 简单! 废了指针不就好了啊~ 。

好的, 我有了一个初步设想了,这个语言应该是

  • 自动的内存管理 (GC)
  • 不需要指针

等等, 对象要是分配到栈上和堆上, 又要不同对待了~ 栈对象肯定和堆对象不一样啊! 如何引用对象成员呢? GC如何区分他们? 哎呀, 好麻烦, 没指针好像就没法区别对待 栈对象肯定和堆对象了! 咋办? 好吧,不允许栈对象就是了嘛! 所有的对象都从堆里分配就好了嘛!真好啊,既然所有对象都是在heap上分配的,区分stack和heap的分配就没有必要了。我可以轻易说 Cat x = Cat() 或者 Cat x = Cat(“mittens”)。

好的, 我有了一个初步设想了,这个语言应该是

  • 自动的内存管理 (GC)
  • 不需要指针
  • 所有的对象都从堆分配,变量只是一个引用

那么接下来是 对象的设计了。面向对象的语言是潮流!

C++ 居然支持 C , 所有的东西不都是对象, 这太恐怖了! 面向对象的语言是潮流!怎么能不面向对象呢? 没对象怎么行! 所以 我的语言必须得是 面向对象的语言! 这个是潮流! 既然面向对象, 就要真正的面向对象 所有的东西都是对象 , 哈哈,这是我从 UNIX 那里学来的,我厉害吧!

啥? main() 函数咋办? 切, 放到一个对象里, 做成 static 成员函数就好了 。。。。。。

为了面向对象的时候, 用起来方便, 我决定,所有的对象都继承字一个叫 Object 的对象! 这样才好! 这才漂亮! 这样不用那难学的模板了, 诶, C++ 的模板太难学了, 肯定大家都和我一样学不会的! 我都学不会,别说一般的程序员了!是吧。 只要大家都是一个根出来的, 用不着写模板, 你的算法就是通用的啦~

而且单个根继承下来, 对 GC 来说也变得容易实现了嘛!

好的, 我有了一个初步设想了,这个语言应该是

  • 自动的内存管理 (GC)
  • 不需要指针
  • 所有的对象都从堆分配,变量只是一个引用
  • 所有的东西都是对象
  • 所有的对象都直接或者间接继承自 Object
  • 所有的方法都是虚的

恩,看起来这样的特性不错, 肯定比 C++ 简单啊~ 大家肯定用的比较 happy 的~ 性能这种东西嘛,丢了丢了, 只要写程序快多好,足矣弥补运行效率的损失了, 再说, 就一个默认虚函数而已, 有啥效率损失。 GC 又不是时刻跑,偶尔出来跑一下啦! 这点效率损失是可以接受的! 带来的好处不用多说, Better C++ 啊!

等等, 异常忘记加了, C++ 都有异常, 咱家咋能没有! 靠!加了加了 !

好的, 我有了一个大概设想了,这个语言应该是

  • 自动的内存管理 (GC)
  • 不需要指针
  • 所有的对象都从堆分配,变量只是一个引用
  • 所有的东西都是对象
  • 所有的对象都直接或者间接继承自 Object
  • 所有的方法都是虚的
  • 支持异常处理

不错, C++ 还有 RTTI , 我的语言怎么能没有? 加了! 还得加的更厚道!

好的, 我有了一个大概设想了,这个语言应该是

  • 自动的内存管理 (GC)
  • 不需要指针
  • 所有的对象都从堆分配,变量只是一个引用
  • 所有的东西都是对象
  • 所有的对象都直接或者间接继承自 Object
  • 所有的方法都是虚的
  • 支持异常处理
  • 支持运行时类信息

哈哈! 这语言已经和 C++ 在特性生很接近了, 差不多了, 但是我需要推出一个 杀手级 的特性! 保证把 C++ 秒到棺材里。

他 C++ 不是号称 “跨平台” 么? 我去! 要到处编译的, 每个平台的编译器还都不一样! 算你妹的跨平台! 咱这语言, 必须真正的跨平台!一次编写, 处处运行!

这TMD的有点意思哈!恩,简单, 咱设计个虚拟机不就完了么! 把咱这个语言的程序用虚拟机跑起来, 只要移植虚拟机就可以了。

恩,最终的语言应该这样的

  • 自动的内存管理 (GC)
  • 不需要指针
  • 所有的对象都从堆分配,变量只是一个引用
  • 所有的东西都是对象
  • 所有的对象都直接或者间接继承自 Object
  • 所有的方法都是虚的
  • 支持异常处理
  • 支持运行时类信息
  • 程序运行在虚拟机上,一次编写处处运行,真正的跨平台

拍屁股决定了语言特性后, 咱就马上开始实现这个语言了! 当然, 实现这个语言还得靠 c++. 否则咱拿什么编译这个语言啊!

这语言写着写着, 咱又发现了几个问题, 首先 int char 这类的类型, 他放到堆上不太好啊!

好吧,打个补丁, 把这几个类型叫做 primitive 类型, 和 C 一样, 分配在栈上好了。


过了一段时间后, 我的主管大力的称赞了我的新语言,然后它被推向了市场, 冠名为 Ksbs 语言。

这个语言引起了很大的轰动, 我很自豪, 因为我把 C++ 所有不好的地方都消灭了, 哈哈哈! 我伟大~

至于 GC 和解释执行导致的效率问题, 我也开始通过更厉害的 GC 算法和 JIT 编译器来弥补了。 我找了几个 benchmark , 证明 GC 比 手工管理内存还快, 另外找了写枪手来批评一下 C++, 整个市场接受度良好! 哼~


在多年的实践里, 我发现了这么一个事实, GC 虽然能管理内存, 但是管理不了其他资源, 比如文件描述符。这些资源程序员必须小心管理, 否则容易发生资源泄漏问题。

我了个去!! 这是很严重的问题! 靠! 怎么没有人告诉我 !! 我听说 C++ 发明了 RAII 机制, 可以自动的管理包括内存在内的一切资源。 这不科学! C++ 一定是垃圾的语言! 我的语言才是最优秀的!

好吧, 加入 finalize 机制好了! 恩恩, 对, 用 finalize 释放其他资源。 哈哈, 我真聪明! 有了 finalize 机制就可以释放其他资源了嘛! 一般的对象都只有内存的啦,所以多一个机制并没有引入太大的复杂度, 对吧?


我很不安, C++ 发明了 shared_ptr , 这玩意, 一下子让我的 GC 黯然失色! 靠, 得想个办法诋毁! 动员公司的力量, 创造舆论! shared_ptr 有原子操作, 多核情况下性能不行!!shared_ptr 无法处理循环引用!

恩恩, 就这样攻击一下, 另外再找几个例子, GC 的性能比 shared_ptr 高的。

果然, 大家都开始唾弃 shared_ptr 了, 说 GC性能更好 ! 恩恩, 我安心了。


但是, 我对摩尔过于乐观了, 我的语言时不时的遭到 “被彻底抛弃,使用 C++ 重写” 的威胁, 我得想个办法!

对! 支持调用 C++ 的程序不就好了! 让他们把比较性能敏感的部分用 C++ 给重写就好了, 别整个重写啊!

对啊, 我还得教育大家, “把性能关键的部分用 C++编写, 其他部分用 ksbs 写” 这样的观念给植入大众的脑袋!总之不能让大家觉得全部用 C++ 写是个更好的选择!


以上就是我设计 Ksbs 语言的历史, 哈哈, 我是 Ksbs 之父!膜拜我吧!


#2

博士,我更加崇拜你了!这也写得出来!


#3

汽车和自行车,有需求就有市场。人类50%是懒惰的。


#4

我擦,博士太强悍了~~


#5

我始终觉得 内存管理 或者宽泛一点的说 资源管理 是一个程序员的基本功,就像内存管理操作系统的五大基本组成之一,这是一个本质复杂的问题,必须要去掌握,只有这样,写出的代码才是经得起考验的。所以为了逃避内存管理而避开C/C++去选择Java之类拥有GC的语言不应当是一个充足的理由。只有这样,你才能去解决那些GC解决不了的问题,这样一来,GC就只是一种辅助,而不是必须的工具,就像在C++中,你可以直接使用new/delete来操作内存,你也可以使用shared_ptr来辅助简化内存管理,这一切是多么的游刃有余。


当然,我还是希望C++中有一个标准且统一的类似于JDK的大而全的library,这对开发效率,代码移植,新手入门都有很大的好处


#6

是的, C++ 的标准库太少了。

Herb Sutter 在 Lang.Next 上说, C++11 和 java 8 C# 4.0 在核心语言上, 大小差不多(比较标准文档的长度得出), C# 稍微小点, java 稍微大点。 C++11 介于二者之间。

但是!!! C# 的 .net 运行时库, 大小是 STL 的数百倍! C++ 最大的问题就是标准库太小了, 以至于很多时候都要写轮子。


#7

C++的标准库确实太少了!就连异步http的库,都要我来造,这说明真是太少了。


#8

C++的标准库这个问题应该是很难解决了,毕竟C#/Java之类的是基于商业化的,背后有一个company来运作,自然工具链,框架,类库都标准化和统一得更好。而C++演变和优化是由一群热心的贡献者在推动,让他们来提供大而全的library有些难,但也是情理之中。另一方面,C++本质上只是一个standard,没有任何的法律约束性,所以,出于自身的利益,每一个C++工具链,商业化支持的提供商都可能为了自身的利益来做一些有悖于C++ standard的事情,C++ CX/CLI就是一个很好的例子,让他们去接受由某一个厂商提供的library更不是一件容易的事情。所以,C++在没有商业化的运作的条件下,要想发展得更好,需要往两方面考虑: 一方面标准化委员会作语言核心层面的事情;另一方面,社区要协作起来,共同构造标准且统一的library提供给开发者使用,类似于boost。让人欣慰的是,这两方面的进展都还不错。当然,C++开发者也要跟着C++的潮流走,使用"Modern C++",而不是"C with class"。


#9

博士说的好,Ksbs还真就是那么回事。