数心开物工作室于6月1日开源发布了一门中文编程语言——青语言,并在开源PHP、博客园等技术社区发布了相关新闻。与预期的一样,中文编程作为一个极具争议性的话题,该新闻一经发布,便收获了较多的关注和评论,其中包括大量的差评,甚至恶评。作为一个开源项目,我们并不介意这样的讨论,也不热衷于与反对者网络对线,所以基本没有对这些差评做出回应。开源项目的发展需要依赖社区的助力,因此我们愿意接受社区的批评和建议,但为了避免对青语言的误解,我们希望通过本文,对青语言的语法设计进行一些说明。
1、青语言可读性差?
关于这一点,我们认为可能更多的是因为编程习惯的原因,而非青语言设计的问题。
首先,青语言的语法设计主要参考了JavaScript。JS是一门成熟且简单的主流编程语言,青语言在语法设计上没有做过多的创新,就是希望在做好编程启蒙的同时,能够让使用者快速地切换到主流的编程语言开发中。基于这一点,我们认为青语言在语法设计上不存在大的逻辑问题,目前也暂时没有收到语法Bug的相关反馈,当然这更可能是因为很少有人愿意深入了解青语言。
其次,示例程序中大部分涉及图形界面编程,这一功能是通过内置标签类型来实现的,大概类似于JSX。并且标签类型使用的是书名号《》来表示,这一点可能会让不熟悉标记语言的读者感到困惑,又或者是单纯的不太适应书名号。
事实上,青语言从一开始设计的时候,就着重考虑了代码的可读性,尤其是我们的目标用户主要是青少年、儿童,此时代码的可读性就尤为重要。由于语法内核参考了Lisp,所以青语言的语法元素非常简单,主要分为变量名、函数名、关键字和符号、数据字面量,代码可读性需要我们能够方便地区分出这些语法元素。在这几种语法元素中,关键字和符号是固定的,数据字面量通过格式区分,符合日常使用习惯。剩下的就是变量和函数,在大多数编程语言中变量和函数名是不进行区分的,但事实上这两者有着本质区别,变量表示某个数据,而函数表示一组操作。所以,为了提高代码可读性,青语言的语法设计上做了如下要求:
以#开头的是变量名
以@开头的是函数名
这样的设计从语法实现的角度来说并不是必需的,而且可能在语法上有啰嗦之嫌,这算是青语言为了提高代码可读性在语法设计上做的取舍。
而这样设计的好处就是能够快速区分变量和函数,例如在JS中出现
a.b
这个时候我们可以知道a是一个对象,但是无法判断b是对象的属性还是方法。而在青语言中则是做了明确的标记:
#a#b ;这是对象a里的属性b
#a@b ;这是对象a里定义的函数b
青语言对变量名和函数名的限定非常宽松,只要使用的是语法符号外的非空字符,都可以支持。虽然我们在示例程序中都使用了中文变量名和函数名,但事实上完全支持使用英文,并不是像一些评论所说的完全排斥英文。使用#和@符号进行标记在简单变量名中显得啰嗦,但是在路径中能够替代成员操作符,并且路径格式更符合中文组词的方式。
采用这一设计的另一个好处则体现在编辑器提示的实现上。为了提高编程效率,我们在发布青语言的同时提供了青语言编辑器,虽然还不够智能,但基于以上提到的语法元素分类的方式,我们通过十分简单的逻辑,提供了基于上下文的代码提示。
2,、青语言使用的符号杂乱
这一问题主要受限于中文字体的显示,当然这个问题完全可以通过输入法设置固定英文符号的方式解决,但是在考虑到语言受众以及实际的显示效果,我们认为这是完全能够适应的,不存在明显的优劣之分,更多的是习惯问题。
下面举个简单的例子,可能不太正确,仅作讨论。在主流的编程语言中,通常使用逗号作为列表项的分隔标记例如JS中我们调用一个函数并传入参数列表:
f(a,b,c,d,e)
f(a, b, c, d, e)
很多时候我们在编写代码时会使用第二行这种方式,也就是每个逗号后面再加一个空格(当然并不是每个人都有这个习惯)。如果你也有这个习惯,应该能够很容易地理解,这个问题简单说就是英文逗号使用的空间小,作为分隔符不明显,同时容易与成员操作符点号混淆。青语言中逗号也作为分隔符,其作用和空格相同,主要是为了从代码显示上便于区分语法元素,那么这个时候,中文逗号能够更好地完成这个功能。
除此之外,与英文符号差别较大的应该就是中文的括号,包括【】和{}以及(),此外还有我们扩展的标签类型使用的书名号《》。这些符号在显示上通常相对于英文符号不够圆润(取决于使用的字体),但相较醒目,容易区分。这一点我们认为是符合青语言的设计要求的,尤其是面向青少年儿童时,比较醒目的符号能够帮助他们更好地区分代码结构,提高代码可读性。
当然,以上是我们目前在设计上的单方面的想法,后续我们还会根据使用者的反馈进行调整。
3、青语言关键字应该支持英文?
这一点完全可以做到,但是我们目前不计划加入到语法实现中。因为如果你打算使用英文,那么我们强烈建议你不要使用青语言,有更多成熟且优雅的编程语言供你选择。而且,青语言在语法上参考JS,就是希望使用者能够快速切换到JS或类似的语言。
以下是关于青语言语法设计的探讨
目前青语言仍处于开发状态,一些语法设计并未完全确定,以下是一些希望和大家一起探讨的问题。
1、对象和代码块
青语言参考JS,但我们发现JS的对象和代码块在设计上都是通过大括号来表示,容易混淆。目前青语言采用了同样的设计,这在教学中可能比较容易造成困惑。同时,由于青语言内核参考Lisp,我们保留了元编程能力(目前并不完整),所以运行时会出现代码块类型,我们使用关键字‘元’来实现这个功能,例如:
元{……}
但这样容易造成一些困扰,因为大括号在一些语句中直接标记为代码块,作为数据的字面值时又表示对象,希望获得代码块类型的数据时又需要添加‘元’标记。
那么这种情况下,可能需要对代码块和对象进行更明确的区分。目前我们设想的一个方案是大括号直接表示代码块,将对象的标记改为:
@{……}
也就是在大括号前多加一个@用作区分。另外,如果后期加上class的话,那么类的构造方法就可以写成:
@类名{}
因为@本身作为函数标记,从语法设计的角度看,能够保持一致。
2、语境(作用域)的设计
首先,语境这个概念继承自Lisp系的Rebol语言,并非青语言强行捏造(PS:Rebol是我非常喜欢的语言^-^)。
这个问题同样是设计一致性的问题,Java中作用域与代码块是一一对应的,但是JS中略有不同,if语句的大括号是不会创建作用域的。目前青语言是参考了JS的方式,这一点我们希望听取大家的意见,确定应该采用哪一种方式。
3、数组访问问题
前面提到的使用#和@作为变量和函数标记,但是目前还存在一个问题,也就是数组中可以放任意类型的数据,然后通过序号(下标)来访问,那么访问的时候可能不能够确定该元素是变量还是函数。目前青语言对数组元素的访问时比较宽松,可以用#和@访问任意类型的数据,没有进行检查。这一点我们也希望和大家一起探讨,看有什么方案可以改进。
以上是关于青语言语法设计的一些说明和探讨的问题,其他可能存在的问题也欢迎大家一起探讨。虽然我们预计本文同样会收到较多差评,但还是希望能够听取不同的声音,作为我们改进的方向。长久以来的编程习惯影响是非常深远的,短时间内难以转变,这一点我们完全理解,但开放与包容可能更利于我们认识世界。