最近沉迷于定义脚本语言,在一些简单实践后,发现如何设计一门语言本身就十分有讲究。错误的定义,往往会导致后期实现和应用脚本时,工作量的翻倍的增长。
那么首先来分析一下c#,java,js在语言级别的基础定义,和他们的区别吧。
语言的基础类型对比
先说说java,就个人而言我不喜欢这门语言,但是把它放在第一个,就可以清晰的看到语言是如何“进化”的。
Java的基础类型是什么?所有引用类型的基础类型Object,以及那些所谓的原生类型(int等),当然,还有接口类型,以及一个无法用Object解释其某些行为的数组类型,和一个用于描述对象类型的Class类。
这些就完整的定义出Java语言的基础要素。关于annotation,枚举,泛型之类的,都是Java的周边组成,没有这些,Java依然还是Java。
看完Java,再看看c#。
c#号称一切都是Object,这确实没错,Object是c#的重要基础之一。为了让Java中的那些所谓的原生类型看起来不那么特例独行,c#耍了个小小的花招,提出了一个值类型的概念。定义值类型时,必须直接继承自ValueType或者Enum这两个类,变相的回到了继承Object的路线(从本质上说,只有boxing form才走这条继承路线,unboxing form下,完全是另一马事)。
另外,接口类型和数组类型,以及Type类型依然是c#中重要语言要素。
不过,除了这些Java中有的要素外,c#提出了个新的要素Delegate,委托是什么,委托就是指代一个或多个方法,c#虽然没能让函数成为语言的第一类成员(First class function,不知道这个该怎么说),但是通过Delegate至少让函数成为了第1.5类成员吧。这导致的直接结果是:在函数式编程领域,人们至少能用c#写出那些不怎么优雅的写法(3.0引入了lambda和Linq则使写法变得优雅了很多),而Java则完全没有发言权。
看了c#后,发现ms虽然统一了原生类型,但是新增加了不少的概念,使看起来简化了的模型,用起来又感觉到复杂。
然后,再看看古老的js,或者说ECMAScript。
由于js是动态类型的,所以类的类型和接口类型就是相对不这么重要的东西了。
js的基础类型(为了方便说明,暂且称之为类型)也是Object,关于原生的数值,js提供了一个Number类型,处理方式与c#很类似,使原生的数值类型看起来并不是整个语言中孤立的一块,而更像是Number类型支持字面量。
而在函数方面,js做的比c#更好,使用了继承Object的Function类型,非常好的做到了first class function。
当然,js的数组也是js中比较特殊的一个类型。
语言的类型自描述
这里说的语言的类型自描述,是指语言化了多少的代价,描述了自己用到的所有类型,包括那些需要特殊处理的类型。
Java拥有最混乱的语言自描述体系,基础类型有Object,int等原生类型,接口类型;和继承自Object的数组类型和Class类型。
c#用最多的概念来维护语言的自描述体系,基础类型有Object,接口类型,值类型unboxing form(如果不关心如何实现的话,可以不知道它的存在);和继承自Object的值类型boxing form,数组类型,Class类型和委托类型。
js用最少的概念就完成了这个任务,Object,和继承自Object的Array和Function。
通过上述的比较,可以发现,js语言方面设计得非常出色。
为了更好的定义自己的语言,决定在未来的3个月内仔细的读一下ECMA-262,吸取其中的核心思想。