财新传媒
位置:博客 > 万战勇 > 宅家里嘎哈?华人圈最骚的dongbei编程语言学习一下!

宅家里嘎哈?华人圈最骚的dongbei编程语言学习一下!

 

~~ 引子 ~~
 
最近,中科院计算所下面的计算机体系结构国家重点实验室部分工作人员发布了一门“完全自主设计、开发和实现,真正掌握了核心技术的面向物联网智能”的国产编程语言木兰。
 
很快有人指出,木兰就是 Python 语言换了个皮肤。
 
我一直嫌弃 Python 社区的口号“人生苦短,我用Python”不押韵。现在好了:人生苦短,我用木兰。
 
老万以前是整编程语言的,知道一门语言的设计实现可以分成语法设计、语义设计、编译前端(源码扫描、语法分析),还有代码生成这几大块。因为木兰目前没有官方文档,难以判断它的语言设计有何特点。不过从网友扒出来的情况看,神似简化的 Python。
 
依我看来,最大的可能是木兰开发组写了一个木兰到 Python 的转换器,执行就直接扔给 Python 了。
 
果不其然,木兰团队承认了。
 
有人说木兰没有任何技术含量。这是不对的。
 
老万估计,这个转换器用字符串替换搞不定,最起码要用到正则表达式。
 
正常情况下,一个大厂的初级程序员需要两到三天的时间完成这样一个程序的开发。
 
你还敢说没有技术含量?How dare you?
 
想到国家科学研究资金只有一小部分(不到99%)被浪费,一个研究组还把超过 1% 的精力用在了实打实的写代码上,我感动哭了。
 
上学的时候,老万读到“昨夜见军帖,可汗大点兵。军书十二卷,卷卷有爷名”,有几个疑问:
 
木兰到底是不是中国人?为啥是可汗在点兵?
爷(木兰她爸)到底啥名?
卷卷有爷名,有必要吗?基本的除重(deduping)技术了解一下?
 
看完新闻,我豁然开朗了,了然于胸了,潸然泪下了:
 
可汗学院(Khan Academy)是全球知名的教育视频点播网站。那里有漫山遍野的 Python 课件,中国程序员在那里出现毫不奇怪。
Python 的爸爸是我的前同事,河南人范贵多(Guido van Rossum)。
《Python 从入门到精通》、《Python 基础教程》、《24小时学会 Python》、......每卷都少不了范大爷的名字。
 
太 make sense 了!
 
~~ 啥是 dongbei ~~
 
用换皮术实现一门编程语言并不神秘。今天老万就给大家演示一下一门叫 dongbei 的编程语言的设计实现过程。
 
之所以叫 dongbei,是因为这门语言的语法设计和关键词选择都是以人民群众喜闻乐见的东北方言为基础,饱含白山黑水的深情。
 
这是一款完全由老万自主设计、开发和实现,真正掌握了基于 Python 3 二次开发技术的以人为本的编程语言。
 
我们知道,世界上有很多很多编程语言,常见的有48式。比如:过程式、函数式、逻辑式、面向对象式,等等!
 
但是居然没有一款以人为本的编程语言?
 
中华文化博大精深,神州方言争奇斗艳,难道不是程序语言设计者取之不尽用之不竭的宝库?
 
就让我来填补一下世界方言编程地图上的这一大片儿空地儿吧!
 
那 dongbei 有啥特点咧?多了去了:
 
简单啊!小学文化程度就行。您能看懂春晚不?能?那就没问题。
好读啊!看着看着包您不由自主地念出声儿来。
开心啊!呃,做人嘛,最要紧的是要开心。
开源啊!不但不要钱,而且不要脸 -- 随时随地欢迎东北话高手打脸指正。
 
这么说吧,谁要是看了 dongbei 程序能憋住了不笑,我敬他是纯爷们儿!
 
以人为本,以德服人。壮哉,dongbei!
 
 
不多扯犊子了。上酸菜!
 
~~ dongbei 方法论 ~~
 
先讲讲 dongbei 语言的方法论。
 
dongbei 编程语言的开发采用了业界领先的 TDD(TreeNewBee-Driven Development,吹牛逼驱动开发)方式。 
 
具体地说,就是老万先在大学同学群立了个 flag,说要开发一门东北方言编程语言。
 
为了兑现吹过的牛,不得不开始开发。
 
在开发之前,每个功能都是先把文案写好,八字没一撇牛皮吹起来。
 
然后根据牛皮写测试案例。
 
最后再实现功能让测试案例通过,牛皮不被吹破。 
 
这样做有两大好处:
 
每个功能都是有的放矢,不值得 tree new bee 的功能一概没有。 
每个功能都有文案吹嘘,开发者绝对不会养在深闺无人识。
 
老万在 pornhub github 有账号,所有 dongbei 语言的开发都在光天化日之下开源进行。不信到 https://github.com/zhanyong-wan/dongbei 瞅瞅。
 
限于篇幅,这篇文章着重介绍 dongbei 语言的特色和使用方式。至于其开发过程请有兴趣的同学自行到 github 围观。
 
~~ Hello world ~~
 
所有编程语言入门第一课必须是打印 “Hello world!”
 
在 dongbei,咱不说“打印” -- 那词儿太膈应了。
 
得说“唠唠”。比如:“今天这事儿咱哥俩儿得好好唠唠。”
 
dongbei 味的 Hello world 程序是这样的:
唠唠:“这旮旯儿嗷嗷美好哇!”。
 
这程序好懂吧:
唠唠:是关键词,显示信息用的。
“唠唠:”后面跟的是要显示的内容。在这儿就是一个字符串。
句号(。)表示操作完了。
 
跑起来结果可想而知,就是在屏幕上显示一句:
这旮旯儿嗷嗷美好哇!
 
按国际惯例,dongbei 程序文件的扩展名是 .dongbei。要是你到 https://github.com/zhanyong-wan/dongbei 去下载 dongbei repo,会在 demo 文件夹看到一个 demo-hello-world.dongbei 文件。要跑它的话,只要 敲命令
src/dongbei.py demo/demo-hello-world.dongbei
就 OK 了。
 
要是试了不灵,肯定是你那系统还没装 python3 呢!那得先装个 python3 去。
 
~~ dongbei 词法 ~~
 
大家知道,大部分的西方语言在书写的时候要用空白字符或者标点把单词隔开,要不就会产生歧义。
 
比如 therapist(理疗师)和 the rapist(强X犯)就有很大的不同!
 
所以,西人开发的编程语言也一样啰嗦,动不动就要加空格,忒麻烦了。
 
dongbei 语言以人为本,适应华人的书写习惯。它的特色创新之一,就是加不加空格换不换行都无所谓。 
 
因为,加了也白加(除非加在一个字符串常量的内部)。 
 
对 dongbei 来说,
  唠
    :
      “嘎哈?”
        。
唠唠:“嘎哈?”。
这两段程序是一样一样的。
 
很有可能,dongbei 是世界上第一门空格键坏了也能使用的语言。
 
Amazing!
 
dongbei 里面数字的表达也可以说是非常贴心。
 
除了用阿拉伯数字表示十进制整数(比如 2、42、250,等等),0 到 10 的常数也可以用中文表达:
零一二三四五六七八九十
其中“二”也可以写成“两”。
 
前面我们讲过,句号(。)可以用来结束一个操作。
 
但对于热情奔放的东北人民,句号显然不够给力。
 
嫑方!
 
dongbei 完全考虑到了用户的情感需求,凡是用句号的地方,都允许用感叹号(!) -- 意思是一样一样的,但是语气强烈,带感!
 
所以,那个嗷嗷美好的程序,也可以改成用感叹号结束:
唠唠:“这旮旯儿嗷嗷美好哇!”!
 
大家在编程的时候,可以根据自己的心情任选使用。
 
~~ 变量 ~~
 
接下来俺们得有变量。
 
不过俺不叫“变量”,那太没特色了!
 
俺们叫“活雷锋”。东北银都是活雷锋嘛。比如:
老张是活雷锋。
 
这句话定义了一个叫“老张”的变量活雷锋。
 
一般来说,“XX是活雷锋。”就是定义一个叫“XX”的变量活雷锋。
 
有了活雷锋,咱得使他。
 
咋使呢?得让他能装点啥。比如
老张装250。
就是让老张装个250,相当于 C 语言
laozhang = 250;
的意思。
 
不光能装个数,还能装别的活雷锋。
 
比如说老王也是活雷锋,要是老张现在装的是 250,那么
老王装老张。
过后老张和老王都装的是 250 了。
 
活雷锋除了会装,加加减减也是常见的操作。按没病走两步的规矩,这些操作的名字叫做:走走、退退、走X步、退X步。
 
比如:
老张装二。# 现在老张等于 2
老张走走。# 现在老张等于 3
老张走两步。# 现在老张等于 5
老张退退。  # 现在老张等于 4
老张退五步。# 现在老张等于 -1
 
 
~~ 运算 ~~
 
四则运算,dongbei 都是杠杠的。举例说明:
 
代码 意思
老王加老张 老王 + 老张
老王减老张 老王 - 老张
老王乘老张 老王 * 老张
老王除以老张 老王 / 老张
 
注意:除法运算叫“除以”,不叫“除”。
 
为啥?
 
问问你小学数学老师就知道,“A除B”的意思是“B除以A”,也就是说“B/A“。
 
所以,要是你说“6除2”,数学老师会以为你在说3分之1,而不是3。你要是跟他讲“6除2得3”,信不信他削你?
 
dongbei 人讲究分寸,长幼有序。除了加减乘除,还会比大小。
 
有这几种操作:
X 比 Y 大
X 比 Y 小
X 跟 Y 一样一样的
X 跟 Y 不是一样一样的
 
假定老王装的是5,老张装的是6。那么
唠唠:老王 比 老张 大。
唠唠:老王 比 老张 小。
唠唠:老王 跟 老张 一样一样的。
唠唠:老王 跟 老张 不是一样一样的。
的结果就是
 
~~ 循环 ~~
 
所谓循环,就是一遍一遍磨叽。 
 
所以,在 dongbei 语言里循环的写法是:
活雷锋名 从 X 到 Y 磨叽:
  ...  # 需要重复做的事
磨叽完了。
举例说明:
老王从一到五磨叽:# 老王从1走到5。
  唠唠:老王!# 打印老王的当前值。
磨叽完了!# 循环结束。
运行的结果是:
1
2
3
4
5
 
磨叽是可以嵌套的。比如:
 
老张从一到二磨叽:
  唠唠:“老张:”、老张。
  老王从老张到四磨叽:# 内层磨叽可以引用外层磨叽变量
    唠唠:“老王:”、老王。
  磨叽完了。# 内层磨叽结束。
磨叽完了。# 外层磨叽结束。
(顿号(、)的作用是把两条信息并列在一起)运行出来是这样的:
老张:1
老王:1
老王:2
老王:3
老王:4
老张:2
老王:2
老王:3
老王:4
 
~~ 讲条件 ~~
 
虽然 dongbei 人都是活雷锋,干活的时候该讲条件还是要讲条件的。 
 
这个讲条件的技能,在 dongbei 里面叫瞅瞅。
 
一般来讲,要是俺们有件事情(不妨叫做 XXX)只想在某个条件(不妨叫 CCC)成立的时候再做,就写:
瞅瞅:CCC 吗?
要行咧就 XXX。
要是 CCC 不成立的时候俺们有另外一件事情 YYY 要做,那就写:
瞅瞅:CCC 吗?
要行咧就 XXX。
要不行咧就 YYY。
 
比如说吧,要是俺们瞅着老王比老张大就想夸夸老王,那就这么写:
瞅瞅:老王比老张大吗?
要行咧就唠唠:“老王比较牛叉!”。
再复杂一点的:
 
瞅瞅:老王比老张大吗?
要行咧就唠唠:“老王比较牛叉!”。
要不行咧就瞅瞅:老张比老王大吗?
要行咧就唠唠:“老张比较牛叉!”。
要不行咧就唠唠:“老王老张共同牛叉。”。
 
看懂了?要是老王是3老张是2,那么这段代码就会打印
老王比较牛叉!
要是老王2老张3咧,就会打印
老张比较牛叉!
要是老王老张都2咧,打印的就是
老王老张共同牛叉。
 
~~ 组合拳 ~~
 
你有没有想过:要是俺们在某个条件成立的时候想做两件事而不是一件事,该咋办咧?要是写
瞅瞅:CCC 吗?
要行咧就
   XXX。
   YYY。
成吗?
 
不成。
 
前面俺们说过,dongbei 语言里面字符串常量外边儿的空白是不作数的。写了也瞎掰活。 
 
所以,按上面这种写法,XXX 倒是只有 CCC 成立的时候才会做,可 YYY 是无论如何都会做的。相当于:
 
# 先讲条件:
瞅瞅:CCC 吗?
要行咧就XXX。
 
# 这个不讲条件。
YYY。
 
要解决这个问题,咱得上 组合拳:把一串操作整合成一个操作。 
 
组合拳的写法是:
开整:
  XXX。
  YYY。
  ...
  ZZZ。
整完了。
尽管整了一串,在 dongbei 语言看来这是一个操作。所以,
瞅瞅:CCC 吗?
要行咧就开整:
   XXX。
   YYY。
整完了。
就能达到俺们的目的了!
 
~~ 套路 ~~
 
“套路”这名字听着吓人,其实就是给一串常用的组合拳取一个名字,然后吧需要做这些操作的时候提一下这个名字就OK了。
 
要定义一个套路,用这个格式:
套路名字 咋整:
  ...  # 要做的操作
整完了。
 
还是举例说明:
写九九表咋整:# 定义套路 写九九表。
  老王从1到9磨叽:
    老张从老王到9磨叽:
      唠唠:老王、“*”、老张、“=”、老王乘老张。# 打印 X*Y=Z
    磨叽完了。
    唠唠:“”。# 空一行。
  磨叽完了。
整完了。# 结束套路定义。
定义了一个叫“写九九表”的套路。
 
注意定义套路本身不会让这个套路真的跑起来。所以上面这段程序跑的结果是啥也不做。
 
要把一个套路代表的操作跑一遍,得写:
整 套路名。
 
比如说,上面这个“写九九表”的套路定义好了过后,你只要写:
整写九九表。
就可以打印出一份浓眉大眼的九九表了:
1*1=1
1*2=2
1*3=3
...
 
 
8*8=64
8*9=72
 
 
9*9=81
 
有的时候,我们希望通过一个参数去控制一个套路的行为。
 
比如,我们要教会电脑算一个数的阶乘(就是1*2*3*... 一直乘到这个数)。在定义这个“阶乘”套路的时候,我们并不知道以后会用它来算哪个数的阶乘。所以,我们要把这个数定义成这个套路的一个参数。
 
那就要这样写:
套路名(参数名)咋整:
  ...  # 爱做的事
整完了。
 
具体到这个“阶乘”套路,就是这样的:
【阶乘】(几)咋整:# 定义套路 阶乘,有一个参数 几
  ...  # 阶乘的操作步骤
整完了。# 定义结束。
 
注意这里我们把套路名“阶乘”用方括号【】括起来,因为“乘”本身是个关键词,不括起来容易引起误会。
 
这个套路有一个参数,名字加做“几”。
 
“【阶乘】(几)”就是算几的阶乘。
 
在“写九九表”这个例子里,套路本身是不返回任何值的。它要做的事都通过“唠唠”打印出来了。
 
而对于“阶乘”来说,我们并不想打印这个阶乘的结果。我们只想把结果返回给整这个套路的人,爱咋用咋用。
 
在 dongbei 里边儿,从套路里返回一个值X,得说“滚犊子吧X。”
 
这个阶乘的完整定义,可以是这样的:
【阶乘】(几)咋整:  # 定义套路 阶乘,有一个参数 几
  老王是活雷锋。
  老王装一。
  老李从一到几磨叽:
    老王装老王乘老李。
  磨叽完了。
  滚犊子吧老王!  # 返回值。
整完了。  # 定义结束。
 
写完这个,再来一句
唠唠:整【阶乘】(五)。
就可以看到打印结果
120
了!
 
~~ 自推 ~~
 
每个程序员在学习编程的时候都要翻一个坎儿,这就是递归 。
 
在 dongbei 语言里面,咱不整这些虚头八脑的概念。咱就叫“自推”。
 
啥意思?就是说在做一个操作的时候调用这个操作自己。有点循环定义的意思。
 
其实这就是俺们中学老师讲过的数学归纳法:欲求 f(n),先求 f(n-1)。然后如果从 f(n-1) 的值可以推算出 f(n) 的值,不就搞定了吗?
 
当然,前提是这个自推不能无穷无尽地整下去,到某一步得停下来。
 
举个例子。
 
求 n 的阶乘 f(n) 也可以这么搞:要是 n 是 0 的话,结果就是 1。要是 n 比 0 大的话,就给就是 n * f(n-1)。
 
这里,在算 f(n) 的时候,我们先算 f(n-1),再从 f(n-1) 算出 f(n)。这就是自推大法的精髓。
 
把上面的思路用 dongbei 语言写出来,就是:
【阶乘】(几)咋整:  # 定义套路 阶乘,有一个参数 几。
  瞅瞅:几比一小吗? # 需要自推吗?
  要行咧就 滚犊子吧 一。  # 不需要。返回 1。
  要不行咧就 滚犊子吧 几 乘 整【阶乘】(几减一)。  # 需要。自推吧。
整完了。  # 定义结束。
 
~~ 结语 ~~
 
dongbei 语言虽然还很稚嫩,但是已经具备了比图林完备性更牛叉的铁岭可玩性,强烈的中华民族性和完美的可口可乐性。三性合一的它尤其适合在特殊时期憋在家里没事找事做的同学们挑战自我。亲子共同学习效果尤佳。
 
dongbei 语言的改进工作正在紧锣密鼓地进行。老万计划在下一版的 dongbei 中加入更多特色功能,为大碴子编程风格的普及做出更大贡献。欢迎大家留言建议、指正。
 
看完了,憋偷懒, 点击此处去 github 免费取 dongbei 全套源代码(绝对不含病毒)、文档、测试代码和示例程序哦~



推荐 12