##编程语言的超集和语法扩展
微软开发了一款编程语言叫TypeScript。对于这款语言的介绍中写道:TypeScript是JavaScript的超集,扩展了JavaScript的语法,因此现有的JavaScript代码可与TypeScript一起工作无需任何修改。
超集的定义是:如果一个集合S2中的每一个元素都在集合S1中,且集合S1中可能包含S2中没有的元素,则集合S1就是S2的一个超集,相对的,S2是S1的子集。如果S1是S2的超集,且S1中一定有S2中没有的元素,则S1是S2的真超集,反过来S2是S1的真子集 。
我们再看回编程语言TypeScript。TypeScript是JavaScript的超集,也就是说,TypeScript在JavaScript的基础上可以使用更多的语法。也就是对JavaScript进行了语法扩展。
我们举个简单的例子。假设有款编程语言A只有加法。如果使用多次的加法运算会非常麻烦。于是我们开发了一款新的编程语言B。我们在编程语言A的基础上新增了乘法,使多次的加法运算更加方便。在不改变编程语言A的基础上,我们扩展了乘法运算。这就是对编程语言A的语法扩展,也可以说编程语言B是编程语言A的超集。
其实现在不只出现了针对JavaScript语法扩展的TypeScript。还有对CSS的语法扩展的Less(Leaner Style Sheets)语言。甚至还有其他编程语言的语法扩展。
这些扩展语言通常会使用和基础语言类似的语法。最后将源代码转换为基础语言的语法结构。我们再回到上面编程语言A和编程语言B的例子。我们在源代码中使用编程语言B的乘法运算后,需要将源代码转化为编程语言A的加法运算。这个过程通常由编程语言B使用自己的命令完成,就像源代码编译那样。也就是说,我们写的乘法运算最后会被转换成加法运算。在这里我们也称编程语言A是编程语言B的超集。
这里需要注意的是,超集的定义是:集合S2中的每一个元素都在集合S1中。也就是说扩展语言是向后兼容的。编程语言A中的所有特性都应该可以在编程语言B中使用。对于C++和C语言,我们通常认为C++是对C语言的扩展,但其实并非如此。C语言中有些特性是无法在C++中使用的。
例如在C和C++中,都可以在一个结构的内部声明另一个结构。
struct box
{
struct point {int x; int y;} upperleft;
struct point lowerright;
};
struct box ad; // C和C++都可以
struct point dot; // C可以,C++报错
box::point dot; // C报错,C++可以
在C语言中,随后可以使用任意使用这些结构,但是在C++中使用嵌套结构时要使用冒号“:”。例如这样在C语言中可以使用,但C++中无法使用的例子还有很多。我们只能认为C++和C语言是两种具有相似特性的不同语言。或者像经常看到的那样说C++是对C语言做了改进。但我们不能说C++是C语言的超集。说C++是对C语言的语法扩展就更加不合理了。
在无法改变基础语言的情况下新增一些方便好用的语法特性是语法扩展的好处。通常这些语法扩展会设计得方便易学,至少不会和基础语言相差太远。缺点可能就是需要花更多的学习和维护成本了。