七阶子博客: 杂文 | 游戏 | 戏剧 | 白蛇 | 文艺 | 编程 | 近期
请输入标题关键字或 yyyymmdd 格式的日期

    也谈中文编程的困境

    #!/usr/bin/env perl
    # The Sieve of Eratosthenes - 埃拉托斯芬篩法
    use Lingua::Sinica::PerlYuYan;
      
    用籌兮用嚴,井涸兮無礙。
    印曰最高矣,又道數然哉。
    截起吾純風,賦小入大合。
    習予吾陣地,並二至純風。
    當起段賦取,加陣地合始。
    陣地賦篩始,繫繫此雜段。
    終陣地兮印,正道次標哉。
    輸空接段點,列終註泰來。
    

    定场诗镇楼!其实这首诗是段程序来着,是 perl 程序(加载了一个特殊的模块叫 PerlYuYan),实现了素数筛分的算法,就是从自然数集中找出 2,3,5,7,11 …… 等素数的工作。这可不仅仅是娱乐功能哟,素数还是现代密码学安全的理论基础呢。

    当然了,仅管这是个严肃的算法应用,但用中文写成却又显得极其不严肃而匪夷所思起来。所以仍然当成娱乐一笑即可。这里我主要是想引申出中文编程这个话题来。

    中文编程的概念提出很久了,但至今还没有个准确的定义,因为也没有足够影响力的产品问世。苟活最久的易语言,差强人意,算得上一种伪中文编程吧。其余的最多算是娱乐探索向的玩具,比如开篇的 PerlYuYan,以及中蟒(python),甚至一些资深 C/C++ 程序员声称,可以谈笑间写一堆 #define 打造出所谓全汉化的表象。

    此外,在 unicode 编码推广后,大多语言都能无障碍地统一处理汉字了,支持以汉字作为变量名,但也很难说这就达到了中文编程的目的。

    既然中文编程本身的概念不清,很自然地,国人对于所谓中文编程的态度也就褒贬不一。但总得来看,大多资深程序员都对中文编程持鄙夷与否定的态度。就我个人而言,在多年前当我作为一个编程爱好者时,乍闻中文编程的宣传时着实兴奋了一番;而今作为一名职业程序员(码农)后,还不时听到有人谈论中文编程时,仔细审视一番,就发现在现阶段中文编程仍是有很大的局限。

    中文编程的拥护者,浅浮些的观点,大约是由于民族主义,与汉字崇拜。认为当前主流的编程语言都是英文的,莫名不爽,应该要有中文编程来抗衡才心安。这是相当外行的观点,从来就没有所谓的“英文编程”,所以也无所谓“中文编程”。如果要说,目前的主流语言充其量叫“字符编程”,不过利用标准键盘上容易输入的那些字符,或者说编码在 128 之前那百余个字符来编程。恰好用少量英文单词来作为关键字或推荐用英文单词(及其缩写)来作变量名,只为助记,非是核心。

    另一些更理性的观点,正是从“助记”这点出发,认为将编程语言全面汉化,使用中文关键字与变量名、函数名等,有助于增加国人程序的可读性与维护性。毕竟,传说中的“最难懂” C 语言编程大赛(最难懂?perl 冷笑了)是没什么实际工程意义的。我们在国内做项目,项目需求本就是用中文表达或讨论的,如果真能中文编程,也确乎能减少思维转换上的负担。有些概念(譬如一些游戏策划脑洞大开的玩法名词概念)是很难找到相应的英文单词来表达的,如果只好无奈用全拼代替,那风格与整体的项目编码规范也是违和的。

    从这个角度看,中文编程是有其意义的,并且也较难完全反驳。一些程序员老鸟只好说“不习惯”。是的,习惯也很重要。如果不能吸引大量一线程序员的支持并且形成良好的社区氛围,别说是中文编程这种另类,就是正常新创的语言也难有前途。

    不过,一些想当然地反对中文编程的人,说中文输入比英文低效,这也是显得外行了。除非你很少打中文,或者根本就是外国人,那么说中文输入比英文慢,那是可理解的。而对于绝大数正常的中国人来说,中文输入是比英文输入快的。

    且不说已经式微的五笔输入法,即使主流的拼音输入法,如搜狗,那输入效率也是非常快与非常智能的了。甚至于可以说,只要有一个通用的中文输入法,进行中文编程时,就几乎可以达到以前编程开发 IDE 呕心沥血研发出的提示补全功能。而对于一个具体的中文编程语言环境,如易语言,更可以定制输入法(或词库)。总之,对于中文编程,中文输入问题,已经是可忽略的细枝末节,其难点,完全不在于此。

    中文编程所遭遇的真正困境,首先是要从汉字的特点说起。 汉字的一个重要特点是语义比较凝固。我们应该感谢汉字的这个特点,以及赢政的书同文功绩,这使得汉字能够稳健地记录与传承几千年的中华文明。中国这么大,各地方言千奇百怪,有统一的文字表示思想与意义,这是很重要的。

    但这与编程有八杆子关系?有的。因为在严肃编程领域,目前的主流还是基于命令式、过程化的编程,典型如 C/C++ 这类语言(这里不细辩所谓面向对象的语言在方法实现时也仍然是需要细致、明确的过程指令)。在编程的过程实现中需要经常性地建立只具有临时语义的局部变量,任一实用语言也需要对变量作用域做仔细的管理,同一个符号在不同作用域指代完全不同的东西(即使在规范命名的情况下它们应该表示有联系的意义,但准确来讲就是表示不同的意义)。而汉字语义的稳定性,在本质上是与编程领域中符号语义的多变性是相悖的!

    汉字,以及英文单词等任一自然语言的文字,它们创造之初都只为表达现实世界的事物、概念与意义。人类所能认识并恰当归纳总结的现实世界,在一段历史时期内是有限的,于是文字也是相对稳定的。而表意的汉字,相比于其他表音文字,则能在更长的历史时期内保持稳定。然而,稳定性在编程的逻辑世界中并不是优点,因为编程中所用的符号,它所要表达的意义变化太快了,并且不一定能在现实世界找到对应物。

    那么,当前的编程语言又是如何解决这个矛盾的呢?答案是不用特意解决,它自然就解决了。因为在编程语言中广泛使用的变量名等标识符根本就不是英文单词,它以英文单词为词根,只为方便程序员提示助记之用,真实实践是在英文单词的基础上进行修饰、拼接与缩写,以达到便捷创建临时语义的符号的目的。另一方面,在英语国家,由于单复数、时态等情况进行各种后缀修饰,以及其他原因的前缀修饰,也已成了习惯语法,所以他们面对编程语言会更有亲切感,更易于接受。

    但是汉字不行,因为每个汉字都是独立稳定的个体,我们不能随意在一个汉字多加一笔画或少一笔画,尤其是数字化时代,非法汉字根本就无从输入。不过在古代,通过改造汉字来表达特殊意义是有先例的,比如古琴谱表示指法的符号,那就是在汉字的基础上改造而来。其实可以将这样的琴谱类比于一段“程序”,不过解释器是受训过的琴师,输出是那首曲子,当然还要有古琴这个硬件。

    然而现在是数字化时代,我们的汉字编码只收录数千个常用汉字。即使 unicode 也只收录有限的合法汉字,不可能收录无穷尽的非法“改造汉字”。除非将汉字当作二维图形来识别,但那效率比英文字母的线性组合低效得多,而且很难规范化。举个例子,假如我们的汉字编码只收录了“木”字,而没有收录“末”与“未”字,只能通过临时在上面多加一横来表示其他临时意义,这长短该如何把握?在现实中,如果不是我们长期的约定,根本很难区分这两个字吧。

    既然无从改造汉字,那就造词吧。但是组词也远达不到英文字母那种随意组合的灵活性。因为字母本身无意义,所以尽管随便组合都不会太违和。但汉字本身是有意义,随意组词是有违中文习惯语法的,很快会变得很拗口。这就与提出中文编程的初衷,增加程序的可读性,貌合神离了。所以,在编程语言的逻辑世界,无意义才有大意义。

    另外,在严肃编程领域,效率始终是要考虑的因素。如果是中文编程,可用字符集在几千数量级,而当前的“英文”编程,字符集在一百数量级。可以想象字符集越小,编译效率就越可能优化得更快。当到最终的机器语言,就只有 0 1 两个符号组合来表达任何意义了。而现代的高级编程语言利用不到一百个字符来表达意义,可能是更好地符合人类的大脑思维特征,因为在历史上有成功案例,英语系国家也就用这几十个字符来表达意义。

    随着硬件性能的提升,在很多现实工程项目中,效率不再最主要考虑的因素。另一方面,由于算法过程的积累与封装,在很多现代脚本语言中都提供了简单易用的库函数,使终端用户的代码编写越来越简单与人性化。也就是说,程序员定义临时变量用以表达细致的逻辑意义的比例减少,而在更高层次上定义变量名表达对应现实世界或项目需求模型的意义的比例增加。在这种趋势下,中文编程的价值会逐渐提升,当然是仅对国人而言,对国人团队限于母语交流项目的情况而言。

    然后另一个挑战出现了,中文编程该具有怎样的风格规范。在契合程序思想与吻合中文语法习惯之间该达到怎样的平衡与代价交换呢?前者是程序可用性与正确性的指标,后者是程序可读性与易用性的指标,对中文母语的国人而言的可读性。

    现存以易语言为代表的“中文编程”的语法与文法,不过是简单的关键字汉化翻译,基本上算是以更复杂的汉字字符编程代替更简单的字母字符编程,实无太大优势。中文编程如果成立,那应该是比字符编程更高一级的自然语言编程。也就是说在保证程序语义精确无歧义的情况下,尽量符合各国本地的自然语言的语法。当前还是字符编程控制领域,新兴的语言都更加追求语法的简洁性。如果向自然语言编程方向发展,在一定程度上语法形式可能会趋于自由与复杂。但随着语音识别技术发展,在源代码(或命令)输入端的效率可以补偿,而解析效率也会由于硬件性能得到补偿。

    于是,符合本地化的自然语言语法习惯的需求会上升,否则,还不如就安静地使用当前的字符编程技术。然而,即使能以中文语法习惯来实现中文编程,也别指望能普及全民编程,实际也没必要。一个简单的类比就如法律条文,虽然每个汉字我们都识得它,但未必每个人都能深刻理解各法律条文的具体含义,所以才需要专业的律师。这同时也表明,虽然中文文学以意境、意象的优美、优雅,或者说有意的模糊性著称,但只要有严肃领域的需求,中文一样也能表达准确、精确的意义。

    所以,假使计算机编程技术会向自然语言编程发展,也仍然需要专业的程序员。即使语音识别的智能成熟发展,自然语言的语音,也该先转化成文字,进而转化为字符,在计算机程序间交流。至于到强人工智能时代,机器人会自己编程了该怎么办,那就是另外的(想象)话题了,暂且不表。

    具体到中文的语法习惯(不论是用于中文编程或其他),我个人有个信仰,就是不能有空格。无他,就是习惯与规范!如果扯到意识形态上,那就是破坏汉字的凝聚力。

    英文需要空格分词,那是无奈之举,纯字母的线性组合必要有可视的分隔符方便人类阅读。但每个汉字都是独立体,天然地自分隔,无需额外的分隔符来标记。实际上,英文中普遍存在的空格,显著地降低了英文的信息密度。在绝大部分领域中的文献,中文都比英文更简洁,或者这空格效应也是一个原因吧。现代汉语的词汇概念,并不对应英文单词,或者可对应短语吧。但是,英文的短语之间,会有更大的空格来表示与单词间的空格不同么?

    所以,像易语言这种语法,也能宣称为中文编程的话,那感觉,就如把好好一句话分成几行来写,然后宣称是新诗一样。你无从反驳,但总是感觉哪里不对……

    不过本文开篇的“定场诗”,就有中文编程的感觉。它采用文言文,不仅是哗众取宠,而是技术上的取巧。因为文言文能用每个汉字单字表示一个意义(程序关键字、变量等),就避免了分词的解析负担。中文分词是个难度不小的算法问题,那是需要专门研究的,其实现复杂度至少不低于正则表达式。

    这个文言文汉语编程,即 PerlYuYan ,其实只是 Perl 语言的一个模块。Perl 这门神奇的语言,其发明者(Larry Wall)的主业不是计算机专家,而是自然语言学家。它可算是探索自然语言编程的先驱,它的很多编程思想与语法特征,都来源于自然语言的习惯与实用主义。当然, Perl 所致敬的自然语言是英语。也难怪 Perl 这脚本语言在国外更流行,而在中国则非常非主流。

    这里无法多讲 Perl 语言的语法特征。不过还想提一下 Perl6 这个项目,那可能是另一个伟大的构想啊。如果 Perl6 完全实现,那就能很轻易地创造或定义出各种方言编程语言,不论英语还是汉语,或者是德语法语等自然语言。我们已经体会到 Perl5 能打造出古汉语编程,那就有理由可期待 Perl6 能打造出现代汉语中文编程。

    其实在现阶段,让中国程序员感觉困难与阻碍的主要不是编程语言有没有中文化,而是缺少可供进阶深入学习的中文文档。用英文文档详叙“英文编程语言”,在库函数名称解释上或有更好的对应,但这不是最关键的。更关键的只是由于高质量的、完整的、及时的文档大都是英文写成的。

    这当然是有历史原因的。其一是中国的计算机科学起步晚,各门派的开山祖师都是外国人吧。其二是中国还不够富裕,大部分程序员都还是搬砖码农,求做房奴而不得的阶段,撸代码尚且不及,哪还有心思写文档。其三是中国还不够强大,之前的教育导向,使得中国最聪明的那部分学生,大都把英文学得比中文好,如果即使在科技(不仅指计算机或编程领域)上有所建树,也自然地习惯用英文来写文档或文章,表达其研究成果。

    所以,这不是中文与汉字的错。很多问题都只是历史与时代的问题,但是我们要用发展的眼光看问题。汉字诚然不适合表达瞬息万变、缺乏具象意义的事物,比如编程中为局部变量命名这种看似简单的事,以及在数学方程式中进行变量演算这种真高大上的事。大凡科技的发展探索方法,不外是归纳与演绎(用中国的文学语言来说,大约就是“以史为鉴,可知兴替”)。汉字不太适合用于演绎,但非常适合用于归纳!

    任一正确实用的科学技术,其基础理论知识都终究会逐渐积累、沉淀、稳定下来(否则那是不是伪科学)。于是,在恰当的时机,用中文来重述与定义这些科学概念与理论,那对中国人(及至全人类)的教育及传承科学知识与文化都是有积极作用的。而且,现代汉语已呈现开放、包容的特征。我们可以很宽容地在中文文档中夹带些英文符号或术语,但是外国人写的英文,你让他插入几个汉字试试?

    一个显著的例子是元素周期表的元素译名。我们用形声字造字法为元素界新造了百余个汉字,这为国人认识理解元素的积极作用已有目共睹了吧。我们不是要用“氢”字来代替元素符号“H”,而是代替其英文名“Hydrogen”。很显然,中文的元素名比英文名更简洁、美观、更有规律,即使我们不是很确定某个元素名念作什么,却至少容易知道它属于气体还是金属或非金属元素。

    结论就是,在现阶段,与其费尽心力去“发明”或翻译中文编程语言,不如去创作或翻译中文编程文档,以及在具体的国产软件工程项目中写好中文注释与文档。这对于提高中国程序员群体的编程水平,或者增加具体项目代码的可读性与可维护性,性价比都会显得更好。

    如果一定要显得自己与众不同,某家倒有一计。为你喜欢的编程语言打个补丁,使中文文档与英文代码自由共存。可归纳为两个凡是规则:凡是引号之外的中文当作注释,凡是中文开头的行当作注释。

    代码文档一体化,是当前许多高级语言的趋势(颇有点古老的 Perl 也是代码文档一体化的,POD 语法)。中文的注释或文档会更简洁,除去母语熟悉度因素。这里所谓的“补丁”虽然似乎无伤大雅,微得不再微的“微创新”,但只为将代码文档一体化的思想贯彻得更彻底。而且每种语言它它它们的注释符号还不一样。每种流行的编程语言都有其哲学思想值得学习,这多少体现在其语法与文法上,但唯独注释符号还真算不上是该语言的语法!

    裸用中文当注释的风格,感觉大约如下:```perl #! /usr/bin/perl

    如果不能对她说,我宁愿去死 open STDOUT, '>girl.txt' or die $!;我一生一世,永远爱你 print "i love u\n" while 1;```

    用中文写注释文档,与字符代码泾渭分明,辨识度很高。即使没有专用编辑器的语法着色,也很容易凭肉眼提取阅读文档。(警告:上面这个 perl 脚本,如果加 # 号将两行注释真注释掉,可在 linux 系统上直接运行,但小心它无限写文件,得强制终止该程序运行。另外在 perl6 中,可用 say 代替 print,似乎更加像说英文了)

    本文是谈中文编程的,上一节却谈到中文文档与注释上去了,不免有偷换概念嫌疑。这里再讨论一个更实用的问题:中文编程,如果成立,又能有什么应用场景?任一新语言,必须要有什么应用领域能体现其有别于现存语言的特长价值,才能得到长足发展。而对于个体程序员来说,学了一门语言也须有用武之地才不致于很快忘记。

    这也是中文编程所遭遇的更大困境。现在市场上已有这么多编程语言了,各具异色,似乎在任何应用场合中都已有更成熟的语言来工作,那又有什么理由来用中文编程语言?仅仅靠情怀来推广,乞怜吗?

    易语言存在了这许多年,似乎仍然还是很小众。据说它现在最大的应用场景是写游戏外挂,发展到这道上可能是有原因的。因为很多游戏玩家也有外挂的需求,他们的主业是玩游戏不是写代码,因此要求编程语言足够简单易上手,开发快(可别要目标游戏都关服了或被下架了还没将外挂研究出来)。于是易语言很好地满足了这个需求,中国人创作游戏的能力还很有欠缺,但玩游戏的智慧却值得点赞。另一方面,游戏外挂实在难算严肃的应用领域,别的严肃语言社区也不会投入太多的关注比例。这个结果恐怕也是易语言本身也始料未及的。

    从中文编程的特性来讲,它并不适合“翻译”那类要求细步过程的命令式语言如 C/C++ (传说有习语言,习佳佳),抽象程序更高的脚本语言如 Python (有中蟒,周蟒)或许会稍微合适点,然而一旦要构建更复杂的程序与工程项目,其缺陷一样会很快暴露出来。另有一类描叙性编程语言(如 SQL),其汉化翻译的可行性又会更高,因为 SQL 语言本身也很像英文。我在网上也看到有些同志提出中文 SQL 的构想,不妨通过以下示例初步感受下其风格(纯属简单的构想示例):

    -- 英文化的 sql 查询语句
    SELECT name, sex, birthday, inparty FROM `Student` WHERE id = 10609114;
    -- 中文可以像这样写
    从《学生表》表中查询编号是 10609114 的“学生”,提取其信息:姓名、性别、生日、是
    否入党。
    -- 或者这样写
    从《学生表》中提取姓名、性别、生日、是否入党,其中编号 = 10609114。
    -- 如果担心解析器的中文分词能力,可以多加些标点符号
    从《学生表》中提取【姓名、性别、生日、是否入党】,其中〖编号〗 = 10609114。
    

    如上所示,按中文规范,中文词汇之间不应加空格,但中文与英文或其他半角字符之间可以加空格。中文虽然没法利用唯一的空格分词,但有更丰富与更有意义的标点符号来辅助分词。先别怀疑像这种【实心中括号】与〖空心中括号〗是怎么打出来的,只要真有这需求,自然会有快捷办法打出来的。

    中文编程另一个可能潜在的价值市场是中小学生教育。因为教育的目标比较特殊,与资本效率市场的追求点可能很不一样。而中文的特点,尤其作为我们的母语,天然地很适合于承载知识与传承文化。

    具体地讲,是在充分研习当代主流编程语言的思想与原理的基础上,结合现代汉语本身的语法习惯,精心择取一个相对小的语法子集,用规定的词汇与句式来表达确定性、无歧义的程序语句。重于教育与理论价值,而暂不竞争工业价值。这样中文编程教育,应该能与中小学语文、数学教育相辅相成(嗯,等中国足够强大了,英语就靠边吧,可以作为兴趣爱好选修,但没必要每人必修吧)。编程与数学相关,这自不必说,但怎么与语文相关呢?试想小学生写作文,那是天马行空的,但写程序,则要求更严谨、准确,否则就是语法错误,无法运行。所以程序作为另一种文体,中文编程有望加强对汉字及标点符号的正确使用的训练。不管学生最终是否会走上职业程序道路,但语文教育对于中国人来讲,始终是重要的。

    举个(构想的)例子:

    我是小学生;
    你是小学生;
    你我一起来玩耍。
    

    假设将这几句当作程序片断来考虑,就如背九九乘法表口诀的儿歌一样的例程。它至少传达了几点编程思想与原则,比如程序变量要先定义类型,“我”与“你”都是小学生类型的变量(或对象),然后方法(函数)调用要匹配类型,“玩耍(我, 你)”要求两个小学生类型的参数。假设还有个“他”不是小学生,那我就不能与他愉快地玩耍了。至于具体怎么玩耍,那就可以继续编故事(编程序)了。

    我似乎还依稀记得,小时候的数学老师教我们三个苹果两个梨是不能相加的,因为无法说清得到五个苹果还是五个梨。如果以当今编程的思想来理解,认为苹果与梨都是继承自“水果”这个基类,那它们就可以相加了,结果可以说是得到五个水果。

    当然了,要为中文编程制定一份完善的语法子集,也不是那么容易的事。但我可以提醒几点。其一是要更加规范标点符号的用法,标点符号是现代汉语的一部分,它们也是有丰富含义的(而文言文是没有标点的,所以句读,俗称断句也成了一门学问)。其次是规范与英文字母等半角符号的混用文法,以开放合作的心态利用好半角符号,几千个汉字加百来个字母符号又有什么可担心的。第三,没有空格的分词复杂度其实没有想象中那么难,毕竟只是有限的规范句式子集,不像任意中文语料的分词有那么多可能的歧义。

    最后总结一下本文的主要观点。

    从来就没有所谓中文编程与英文编程的对立,只有字符编程向自然语言编程的发展可能性。目前看来,中文编程最大的优点是情怀,最大缺点是不习惯。我们要充分认识汉字的特点,独立稳定的语义,重归纳轻演绎的传统,尽量让汉字做它恰如其分的事情。汉字的地位是与国运联系的,也许当中国真正强盛与复兴之时,才更能突显中文编程的价值。

    然后附带两则广告。

    一是易语言。作为最早产品化的中文编程项目,还是值得中肯的评价。它适合没有编程基础也不想以编程为职业的国内用户,它官方提供的 IDE 使得它也不完全是汉化字符的编程,而有点像图框式的编程。大凡办公室长期工作的,如能找到个程序化工具帮忙将经常重复性的工作辅以自动化或半自动化完成,提高日常工作效率,那是值得的。能做类似工作的还有诸如按键精灵这类的软件,它们不标榜为语言,争议也就没那么大。

    二是 Perl 与 Perl6 语言。Perl6 不是 Perl 的高版本,而算是另一全新的语言,将在自然语言化编程的道路上走得更远。如果 Perl6 能完全成熟,那也就相当于从一个维度开启了人工智能的曙光。因为通过它的自定义语法,能让计算机理解各国的自然语言的文字,也就能让人们通过自然语言去命令计算机执行工作。