财新传媒
位置:博客 > 万战勇 > 【老万】dongbei 语言满月记事

【老万】dongbei 语言满月记事

 

dongbei 编程语言自打呱呱坠地就激起了公奋,银民群众的殷切期望如滔滔江水罄竹难书。
 
兹摘录评论数则。
 
有对项目水平做出中肯评价的:
 
“陈独秀比起你来都差点。”
“过于沙雕。”
“东北从此有四宝。”
“无聊,和农民造飞机一个德行。”
“这种东西编译器课程认真做作业的花点时间都能捣鼓出来吧。”
“你这不像是编程语言,更像是语音助手。。飙泪笑”
 
有描述使用过程生理反应的:
 
“劲太大了,给我整上头了。”
“把我头笑掉了你拿什么赔?!”
“寻思看个文章我咋自动带入语音了害?”
 
有给老万的人生之路指点迷津的:
 
“作者可以去中科院了。”
“千万资金属于你。”
“中科院点了个赞.jpg”
“还是静下心来做真正的研发吧,老实说,中国已经过度的娱乐化了,现在连技术都要娱乐化吗?一个翻译语法的外壳而已,咱们不可能靠这些娱乐化的东西来打退别人的技术封锁,更不可能造成战略优势的!”
 
有失足青年要痛改前非的:
 
“哈哈哈哈感觉我要爱上编程了哈哈哈。”
“我搁家躲病毒,圈得五脊六兽的,一看着这玩意儿,齐了咔嚓地就给它念完了!这家伙,早前儿电脑要有这好玩意儿也不至于程序一捅咕上就跟划不开拐抢不上潮似的!”
“咱这东北老爷们儿这不都给你们这帮憋犊子祸害成整电脑的了。”
 
还有对老万的身体状况殷殷关切的:
 
“这都要从一只蝙蝠说起。。。”
“就想问问是不是在家闲出病来了。”
“来人啊,又憋疯一个!”
 
看到这里,你是不是已经按捺不住,急赤白咧,上蹿下跳了呢? 
 
嫑急吼吼。在 dongbei 语言满月之际,咱们来慢慢悠悠瞅一瞅都有哪些新成果。
 
~~ 可用性改进 ~~
 
从前,使用 dongbei 语言需要先下载/克隆俺们的 github 仓库,然后再用 src/dongbei.py 去跑程序。能用是能用,跟别的语言比方便性稍逊风骚。
 
在 xinxiao 老铁帮助下,大伙可以用 pip3 直接撸最新版(目前是0.0.6版)的 dongbei 了:
# 给这台电脑的所有用户安装
$ pip3 install dongbei-lang
 
# 只给自己安装
$ pip3 install dongbei-lang --user
 
# 更新到最新的 dongbei 版本。要是只给当前用户更新,加 --user
$ pip3 install dongbei-lang --upgrade
 
装好了就可以这么用了:
$ dongbei demo/磨叽.dongbei
 
harrywang 老铁觉着没有虚拟环境忒费劲,就整了个对虚拟环境的支持:
$ python3 -m venv venv
$ source venv/bin/activate
$ pip install -r requirements.txt
 
为了让大家在用 dongbei 编程的时候如虎添翼,如鱼得水,如痴如醉,如胶似漆,还有两位老铁出场了:
 
mingjun97 整的 VS Code dongbei 语法高亮度插件:  https://github.com/mingjun97/dongbei-vscode  。大家可以在 VS Code 插件商店直接安装。
suxpert 搞出了 vim 的 dongbei 语法高亮度和自动补全插件: https://github.com/suxpert/dongbei.vim ,整法自个儿到项目主页瞅去。效果杠杠的:
 
 
~~ 语言特性改进 ~~
 
短短一个月,dongbei 语言憨吃疯长,get 了不少新的语言功能。来瞅瞅:
 
变量操作
 
大家知道,要把一个变量活雷锋的值清空回到原始状态,可以用削:
削 老王。  # 跟 '老王 装 啥也不是。' 意思一样,可是带感啊!
过后老王就啥也不是了,但是名字还在。所以接下来
老张 装 老王。
还是可以的,结果是老张也变成 啥也不是。
 
现在 dongbei 学会了更狠的操作 炮决:
炮决 老王。
过后老王就香消玉殒,尸骨无存了,连名字都留不下。
 
这时候,要是再来
老张 装 老王。
就会爆出一个错了。
 
双向交流
 
刚出生的时候,dongbei 还在自说自话,只会 唠唠,没法听懂别人的吩咐。
 
现在好了,可以整 你吱声 来获得用户输入:
贵姓 装 整 你吱声(“你贵姓?”)  # 打印消息,然后等输入。
唠唠:“名字呢?”
名字 装 整 你吱声。# 不打印消息,等输入。
唠唠:“你揍是传说中的”、贵姓、名字、“啊!”。
 
整除和余数
 
除了一般的除法,dongbei 现在也会整除和求余数了。
七 齐整整地除以 三
得2(7除以3的整数部分)。
七 刨掉一堆堆 三
得1(7除以3的余数)。
 
群众
 
单只单只的活雷锋有的时候略显捉襟见肘。dongbei 支持“群众”的概念。就是一个变量里放一群活雷锋。
 
有学习好的同学可能发觉了:这不就是数组吗!
 
要定义一个数组一伙群众,可以用 “XXX 都是活雷锋”。比如:
张家庄都是活雷锋。 # 张家庄是个群众变量。初始值是「」。
完了吧就可以用 装 或者 来了个 往里边儿加人了:
张家庄 装 「二加三,“大”」。  # 张家庄现在 = 「5, '大'」
张家庄 来了个 四减一。  # 张家庄现在 = 「5, '大', 3」
张家庄 来了个 “粗”。   # 张家庄现在 = 「5, '大', 3, '粗'」
加完人就可以点名了:
唠唠:张家庄的老大。  # 第一个人(5)。
唠唠:张家庄的老二。  # 第二个人('大')。
唠唠:张家庄的老(四减一)。  # 第三个人(3)。
唠唠:张家庄的老四。  # 第四个人('粗')。
唠唠:张家庄的老幺。  # 最后一个人('粗')。
要想无视老大或老幺,可以分别用 掐头 和 去尾 运算。比如:
唠唠:张家庄掐头。# 「'大', 3, '粗'」
唠唠:张家庄去尾。# 「5, '大', 3」
注意 掐头 和 去尾 只是运算,它们返回一个新的群体,不会真的去修改 张家庄。所以,上面的操作弄完后,张家庄 还是 「5, '大', 3, '粗'」,一个也不能少。
 
既然数组里头可以套数组,那么群众当中也可以套群众:
李家村 都是活雷锋。# 李家村也是个群众变量。初始值是「」。
李家村 来了个 三。# 李家村现在 = 「3」。
李家村 来了个 张家庄。# 李家村现在 = 「3, 「5, '大', 3, '粗'」」。
唠唠:李家村的老幺的老大。# 5。
也可以用 来了群 一次把一个村庄的群众挨个加入到另一个村庄。比如,要是李家村 = 「1,2」,张家庄 = 「3,4,5」,那么
李家村 来了群 张家庄。
过后,李家村 = 「1,2,3,4,5」,而张家庄还 = 「3,4,5」。
 
要是想一次加多个群众,可以用「1,2,3」或者 路银「1,2,3」这样的说法:
李家村 来了群 「9,2,3」。
#也可以说:
李家村 来了群 路银「9,2,3」。
 
要数数一个数组里有几个元素,用 XX 有几个坑:
# 假定 张家庄 = 「1,2,3,4」
唠唠:张家庄有几个坑。# 4
 
国有国法,村有村规。村子里要出了不法之徒,可以依法 炮决。
 
假定一开始张家庄 = 「5, '大', 3, '粗'」。
炮决 张家庄的老三。
过后,张家庄就 = 「5, '大', '粗'」了。
 
社团
 
和参加群众性活动类似,活雷锋们还可以通过 抱团 操作组成社团。
 
一个群的成员数可以是 0,1,2,3...... 
 
同样的,一个社团的成员数也可以是 0, 1, 2, 3......
 
比如:
圣人团 装 抱团。  # 空社团
独孤求败团 装 西门吹雪 抱团。  # 一个人的社团:(西门吹雪,)
【二人转团】 装 赵英俊 跟 高老师 抱团。# 两个人的社团:(赵英俊, 高老师)
桃园社 装 老刘 跟 老关 跟 老张 抱团。# 三个人的社团:(老刘, 老关, 老张)
唠唠:桃园社 有几个坑。# 3
抱团之后,可以用 老几 操作访问团员:
唠唠:桃园社 的老大。# 老刘
唠唠:桃园社 的老二。# 老关
唠唠:桃园社 的老幺。# 老张
那么你要问了:这个群和团到底有啥不一样?说叨说叨?
 
问得好啊!
 
区别在于:群是松散的组织,而社团有严格的定义。
 
群众是来去自由的,还可以变来变去:
张家庄 装 「5,3,2,4」。
张家庄 来了个 7。    # 变多了:「5, 3, 2, 4, 7」
炮决 张家庄的老大。  # 变少了:「3, 2, 4, 7」
张家庄的老二 装 九。  # 变节了:「3, 9, 4, 7」
团就不一样了。一朝入团,终身不悔。
 
一个团一旦定义好了,就不能有任何改变。
 
啥 XX团 来了个 YY,XX团 来了群 YYY,炮决 XX团的老二,XX团的老幺 装 YY,......这些妄想改变团成员的操作,整个儿都是徒劳的。
 
切记,切记。
 
花式磨叽
 
我们知道,dongbei 语言通过 磨叽 操作实现循环。
 
引入群众和社团变量之后,磨叽 的范围也可以是群众/社团。
 
比如,要是张家庄装的是「3,1,5,2」,那么
老王 在张家庄 磨叽:
  唠唠:老王。
磨叽完了。
的结果就是
3
1
5
2
要是磨叽到半拉儿就不想再磨叽了咋办咧?那就 尥蹶子。
 
要是想跳过从当前到 磨叽完了 中间的所有操作,就说 接着磨叽。
 
比如这个:
老张 从一到十 磨叽:
  寻思:老张跟二一样一样的?
  要行咧就 接着磨叽。
  唠唠:“老张是”、老张。
  寻思:老张比五还大?
  要行咧就 尥蹶子。
磨叽完了。
结果就是
老张是1
老张是3
老张是4
老张是5
老张是6
注意老张是2的时候,因为“接着磨叽”被执行,“唠唠”就被跳过了。
 
要是想 死磨叽,可以 从一而终:
老王 装 一。
老张 从一而终 磨叽:# 磨叽无穷次,每次的值都是一。
  唠唠:老张、“和”、老王。
  老王 装 老王加一。
  寻思:老王比三还大?
  要行咧就 尥蹶子。
磨叽完了。
结果就是
1和1
1和2
1和3
 
叉劈
 
很多的时候,要是一个前提条件不成立,咱们就想立马尥蹶子退出整个程序,因为它意味着上游提了个不合理的要求。
 
虽然理论上说 寻思 可以处理这种情况,实际用起来相当啰嗦。
 
这时候咱们就可以用 保准 CCC,非常精炼。
 
比如:
保准 老王比五还大。
要是老王的值比五还大咧,这句话没毛病,程序接着往下跑。如若不然,程序立马退出,而且打印出一条错误:
整叉劈了:该着 【老王】比5还大,咋有毛病了咧?
还有的时候咧,咱们要保准某个条件不成立。
 
跟保准相对的是 辟谣:
老王 装 二。
辟谣 老王比五还大。  # 没毛病 - 这确实是谣言。
辟谣 五比老王还大。  # 整叉劈了:5比【老王】还大不应该啊,咋有毛病了咧?
严格来说“辟谣”并不是东北特有的词汇,但是东北人民对它可以说是相当的熟悉了。所以把它收入 dongbei 编程语言是相当和谐的。你明白了吗?
 
善用 保准 和 辟谣,保准臭虫在你代码里藏不住。
 
要是写 整叉劈了:XXX 咧,就会让程序马上打印 XXX 然后退出。比如:
寻思:小王比18还小?
要行咧就 整叉劈了:“小王只有”、小王、“,小朋友请回避!”。
会在小王装16的时候打出消息
整叉劈了:小王只有16。小朋友请回避!
然后立马退出。
 
阶级
 
伟大领袖 XXX 教导我们,银一出生就打上了阶级的烙印。一个银,不属于这个阶级,必然属于那个阶级。超越阶级存在的银,是不可能的。
 
所以,在 dongbei,所有的活雷锋都可以根据他们拥有的财产(洋文叫 properties)划分成不同的 阶级(class)。
 
银的财产是可以继承的。老子的财产,儿子都可以有。按照这个财产继承的关系,不同的阶级可以分出三六九等。
 
最高高在上的,是无产阶级。顾名思义,无产阶级没有任何财产(properties)。
 
在 dongbei,我们可以用
XX阶级 的接班银 YY阶级 咋整:
  ...
整完了。
来定义一个叫 YY 的新阶级。每个 YY 阶级的成员,都继承了 XX 阶级的全部财产。
 
比如:
无产阶级 的接班银 YY阶级 咋整:
  ...
整完了。
 
要给一个阶级创造一个新的对象,先定义如何初始化这个对象:
无产阶级 的接班银 有名阶级 咋整:
  新对象(名字)咋整:  # 要初始化一个有名的对象,得提供一个参数(名字)。
    俺的名字 装 名字。  # 把这个对象的名字设成提供的参数。
  整完了。
整完了。
完了吧就可以按需分配对象了:
# 创建一个有名阶级的对象,他的名字参数是“林蛋大”。
老林 装 有名 的新对象(“林蛋大”)。
然后咧就可以使用这个对象的财产了:
唠唠:老林的名字。# 打印:林蛋大
 
前面说过,阶级之间是有继承关系的。要是阶级乙是从阶级甲继承来的,那么在创建阶级乙的新对象的时候,需要先创建阶级甲的对象:
有名阶级 的接班银 特有名阶级 咋整:
  新对象咋整:
    # 先按有名阶级的方法初始化这个对象。
    整 领导的新对象(“赵英俊”)。
    # 再加一些特有名阶级的操作。
    俺的 年龄 装 25。
  整完了。
整完了。
 
老赵 装 特有名 的新对象。# 创造对象
唠唠:老赵 的 名字。# 赵英俊
唠唠:老赵 的 年龄。# 25
一个阶级的成员除了有财产,还可以有自己的套路。
 
定义阶级套路的办法跟定义普通套路是一样的,只要把它的定义放在一个阶级内部就好了。
 
在阶级套路里面,可以直接使用一个叫 俺 的特殊活雷锋。俺 指代当前对象。比如:
有名阶级 的接班银 特有名阶级 咋整:
  ...
  公岁 咋整:
    滚犊子吧 俺的年龄 除以 二!
  整完了。
 
  显呗 咋整:
    唠唠:“我你都不认识啊?我是那啥”、俺的名字、“!”。
  整完了。
整完了。
定义完阶级套路过后,只要有一个这个阶级的对象,就可以整这个套路了:
老赵 装 特有名 的新对象。
唠唠:老赵 整 公岁。# 12.5
老赵 整 显呗。# 我你都不认识啊?我是那啥赵英俊!
 
帮衬
 
在家啃父母,出门靠姐妹儿。
 
甭管你多大能耐,没人帮衬也不成。
 
所以咱们写 dongbei 程序得借力,憋啥玩意儿都自己从头整。
 
比如翠花蛇家宝贝不少,咱就借来用用呗。
 
举例说明,
翠花,上 re。# 导入 python 的正则表达式 re 模块。
老王装“abd”。
寻思:整re.match(“a.*”,老王)?# 调用 re.match()。
要行咧就唠唠:“OK!”。
要不行咧就唠唠:“砸了!”。
跑出来结果
OK!
 
最高指示
 
最高指示 是一个特殊的名字。它是一个群众变量,装的是当前运行的命令行。
 
比如有一个程序是这样的:
# a.dongbei
唠唠:最高指示。  # 打印当前命令行。
那么,执行
src/dongbei.py a.dongbei 今天 风大
的结果就是
「'a.dongbei', '今天', '风大'」
 
打盹
 
干活太快不一定是好事。
 
比如在做动画的时候,动得太快了会把大伙儿眼睛晃瞎的。
 
要是想歇两秒再接着干,可以
整 打个盹(二)。
 
以此类推,多歇几秒也是可以的:
# 睡个半小时。
整 打个盹(30 乘 60)。
 
~~ 示例精选 ~~
 
这里还有一些精选的示范程序供大家参考:
 
xinxiao 老铁的快速排序
 
这个程序演示了如何用 dongbei 实现经典的快速排序算法。相信算法挂科的同学们看了这段代码都会如梦方醒,恨老万为啥没在他们算法考试前捣鼓出 dongbei。
排得贼快(村子)咋整:
  寻思:村子有几个坑 跟 零 一样一样的?
  要行咧就 滚犊子吧 村子。
 
  杆子装村子的老大。
  几个杆装零。
  矮墩庄都是活雷锋。
  高个庄都是活雷锋。
  哥们儿 在 村子 磨叽:
     寻思:哥们儿 跟 杆子 一样一样的?
     要行咧就 几个杆走走。
     要不行咧就寻思:哥们儿比杆子还小?
     要行咧就 矮墩庄来了个哥们儿。
     要不行咧就 高个庄来了个哥们儿。
  磨叽完了。
 
  顺溜庄都是活雷锋。
  矮墩 在 整 排得贼快(矮墩庄)磨叽:
    顺溜庄来了个矮墩。
  磨叽完了。
  还行从一到几个杆磨叽:
    顺溜庄来了个杆子。
  磨叽完了。
  高个 在 整 排得贼快(高个庄)磨叽:
    顺溜庄来了个高个。
  磨叽完了。
  滚犊子吧 顺溜庄。
整完了。
 
乱炖庄 都是活雷锋。
乱炖庄 来了群 路银「二,三,七,六,二,八,二,一」。
 
唠唠:整 排得贼快(乱炖庄)。
运行结果:
 
「1, 2, 2, 2, 3, 6, 7, 8」
 
老万的汉诺塔动唤
 
汉诺塔是另一道知名递归算法题。老万演示了如何通过导入 python 的 curses 模块实现动画效果。
 
翠花,上 curses。
 
无产阶级 的接班银 汉诺塔 阶级咋整:
  新对象(白纸,几层)咋整:
    俺 的 白纸 装 白纸。
    俺 的 几层 装 几层。
    俺 的 柱子堆 装 「「」,「」,「」」。
    楼层 从 一 到 几层 磨叽:
      俺 的 柱子堆 的 老大 来了个 楼层。
    磨叽完了。
  整完了。
 
  画画 咋整:
    俺 的 白纸 整 clear。  # TODO: 允许省略“俺的”。
    整 curses.curs_set(鸭蛋)。
    大盘子多宽 装 俺 的 几层。
    柱子距离 装 大盘子多宽 乘 二 加 四。
    桌面 装 俺 的 几层 加 三。
    俺 的 白纸 整 addstr(桌面,二,(柱子距离 乘 三 加 一)乘 “-”)。
    多远 装 大盘子多宽 加 四。
    柱子 在 俺 的 柱子堆 磨叽:
      层数 从 鸭蛋 到 俺 的 几层 磨叽:
        俺 的 白纸 整 addstr(桌面 减 层数 减 一,多远,“|”)。
      磨叽完了。
 
      几个盘 装 柱子 有几个坑。
      盘子号 从 一 到 几个盘 磨叽:
        盘子多宽 装 柱子 的老 盘子号。
        俺 的 白纸 整 addstr(
            桌面 减 几个盘 加 盘子号 减 一,
            多远 减 盘子多宽 减 一,
            “(”、(盘子多宽 乘 二 加 一)乘“=”、“)”)。
      磨叽完了。
 
      多远 走 柱子距离 步。
    磨叽完了。
    俺 的 白纸 整 refresh。
    整 打个盹(0.5)。
  整完了。
 
  挪挪(哪儿来,去哪儿)咋整:
    顶楼 装 俺 的 柱子堆 的老 哪儿来 的老大。
    炮决 俺 的 柱子堆 的老 哪儿来 的老大。 
    俺 的 柱子堆 的老 去哪儿 装 (「顶楼」 加 俺 的 柱子堆 的老 去哪儿)。
    俺 整 画画。
  整完了。
  搬楼上(楼上几层,哪儿来,去哪儿)咋整:
    寻思:楼上几层 跟 鸭蛋 一样一样的?
    要行咧就 开整:
    整完了。
    要不行咧就 开整:
      哪儿歇 装 六 减 哪儿来 减 去哪儿。
      俺 整 搬楼上(楼上几层 减 一,哪儿来,哪儿歇)。
      俺 整 挪挪(哪儿来,去哪儿)。
      俺 整 搬楼上(楼上几层 减 一,哪儿歇,去哪儿)。
    整完了。
  整完了。
 
  搬家(哪儿来,去哪儿)咋整:
    俺 整 画画。
    俺 整 搬楼上(俺 的 几层,哪儿来,去哪儿)。
  整完了。
整完了。
 
几层 装 整 你吱声(“你要搬几层?”)。
寻思:几层?
要行咧就 几层 装 整 int(几层)。
要不行咧就 几层 装 二。
 
汉诺塔动唤(白纸)咋整:
  汉诺塔 的 新对象(白纸,几层) 整 搬家(一,二)。
  整 打个盹(三)。
整完了。
 
整 curses.wrapper(汉诺塔动唤)。
运行结果:
 
 
~~ 结语 ~~
 
关于 dongbei,这个月咱就唠叨到这儿。直达 dongbei 项目主页儿: https://github.com/zhanyong-wan/dongbei 。老铁们,都多帮衬点儿啊!



推荐 0