查看原文
其他

这个奇葩的语言,代码写完后连作者自己都看不懂了!

码农翻身刘欣 码农翻身 2021-04-27

周末的Hello World咖啡馆依然热闹非凡,Java,Python,Lisp等一伙人坐在一起谈笑风生。这时候Java注意到门口来了一个面色阴郁的老头儿,在咖啡馆门口徘徊着,似乎不愿意进来。


Java上去询问, 老头儿说他叫Forth,被主人设计成了一幅古怪的模样,现在没有多少程序员愿意用了,失去了往日丰厚的收入,只有流落街头。


Lisp笑道:“你坐什么来的?”


老头儿说:“骑电动车。”


“我们坐的都是奔驰、劳斯莱斯,你骑电动车!你骑电动车Hello World咖啡馆都不让你进来啊!”


Java邀请老头儿入座:“别听Lisp胡扯,你说说,你被设计成了什么古怪模样?”


Forth 说:“我被设计成了一个基于栈的编程语言,你看看,比如你要计算 3 + 4 . ,得这么来......” 


Forth说着从怀里掏出了几张漫画。


(第一步:把数字3入栈) 

(第二步:把数字4入栈) 


(第三步:从栈中取出4和3, 执行3+4, 把结果7 入栈) 



(第四步:从栈中取出数字7, 在屏幕上显示)


 (图片来源:https://www.forth.com/starting-forth/1-forth-stacks-dictionary/)


Java 一看就乐了:“哈哈,漫画不错啊,这不和我Java是一样的吗?我也是基于栈的虚拟机啊。不信你看看码农翻身介绍我的文章《我是一个Java Class》。”  


Python也乐了:“没错,我也是基于栈的虚拟机,咱们的工作方式是一样的。” 


Forth疑惑的问道:“是吗?难道你们也是如此? 是不是还有很多程序员在雇佣你们啊?我看你们乐呵呵的,穿着光鲜亮丽,开豪车,工资不低吧?”


“一般一般,富裕谈不上,最多是个小康。既然咱们差不多,你怎么这么落魄啊!”  Java问道。 


“唉,我还没有给你说我的编程语法呢, 比如你要计算(3+4)* 5 ,程序员得这么写:” 


 3 4 + 5 *    


Java和Python都大吃一惊:“难道今天遇到传说中的后缀表达法了? 这种写法可就太让程序员崩溃了。” 


只见Lisp撇撇嘴:“小样,这就崩溃了,比我的前缀表达式差远了  (* (+ 3 4) 5 ) ”  


Java不动声色:“那你如何定义一个函数呢?比如这个计算平方的函数 ” 


public int square(int x){     

    return x * x; 


Forth说:“在我这里不叫函数,叫Word, 程序员需要这么定义。” 


 : SQUARE DUP * ; 


(注:冒号表示开始定义,分号表示结束定义) 


Java看到了熟悉的DUP,说到:“你这里也有DUP啊,我的字节码指令也用到了,它是把栈顶的元素复制一份,再压入栈中, 但是你这里怎么没有参数啊?” 


“你这么快就忘了,我是一个基于栈的编程语言啊,参数会被放到栈中啊, 比如你想计算10的平方,需要这么调用:10 SQUARE, 展开后就相当于 10 DUP *” 


10 先被压入栈中,DUP会把栈顶的元素复制一份,再压入栈中。这样栈中就有两个数字了,都是10 , 最后再调用乘法。



看到Java略有惊讶,Forth说:“这还不算什么, 你看看我的IF语句。” 


 : ?Negative 0 < IF  ." less than 0"  THEN ; 


这是测试一个数字是不是小于0 


-3  ?Negative    会输出 less than 0。



Java忍不住说到:“我去,有点变态啊,我的脑子中得时刻想着有一个栈,所有的操作都是基于这个栈的!”


Forth有点惊讶:“你不是说你是基于栈的虚拟机吗?怎么?和我不一样吗?” 


“我们的虚拟机确实是基于栈的,但是我们的语法可是正常的语法啊 !程序员写的时候,用的是最熟悉的中缀表达式。”


 ( 3 + 4 ) *  5 ;  


“还有函数调用,也是符合直觉的,编译成字节码以后,才会在基于栈的虚拟机上执行,有很多不求甚解的程序员都不知道我是基于栈的虚拟机!” 


square(30); 

is_negative(-3); 


Python向Forth投去了同情的目光:“你的主人是怎么想的?让程序员在编程的时候,时刻记住有个栈的存在,多累人啊!” 


“我主人说了,基于栈的编程语言非常容易实现,所以非常适合那些内存很小/计算能力受限的计算机,对了,你知道打印机所使用的PostScript吗?它也是基于一个基于堆栈的编程语言。” 


大家都表示对PostScript不熟。 


Forth说:“我举个更简单的例子,比如表达式计算吧,如果用你的中缀表达式 (3+4)* 5  ,你在实现的时候得先做词法分析,然后做语法分析,形成抽象语法树,必须考虑优先级问题。



Java说:“难道不应该这样吗?形成抽象语法树(AST)是个通用操作啊。” 


Lisp马上插嘴:“AST大法好,你看我的前缀表达式,天然就是抽象语法树啊,  (* (+ 3 4) 5 ) , 我的代码和数据的表示方式是一样的,代码可以被当作数据来修改...... 算了,说了你们也听不懂。” 


Forth说:“我就不用这样,你看用后缀表达式,再加上栈,可以直接计算,多方便。”



Java感叹道:“编译的过程包括词法分析,语法分析,语义分析。我看你的程序甚至不用做语法分析,只要做一个词法分析,也就是分词,然后就可以直接计算了!”


 “是啊,我的语法非常简单,或者说几乎没有什么语法,我的主人说我可能是世界上最简单的语言了!” 


Java 问道:“既然你这么简单,怎么没有流行起来啊?” 


“这个......其实也不能算简单,无论是编写程序还是阅读程序,脑子中时刻得想着那个栈,对程序员自身的思维水平要求太高,一般人是受不了的, 有人笑话我是一个write-only的语言,写完以后连作者自己都读不懂了。” 


这几个人都笑了起来。只有Lisp在撇嘴:这还要求高,你还没见过我的宏......  


Forth 喝了一杯咖啡,颤巍巍地站起来,骑上门口的电动车,一溜烟地离开了。Java 注视着他的背影,心中感慨,这个Forth是一个老兵,他和Lisp一样,那种“古怪”的表达方式对广大程序员来说都不太友好,想流行起来很难啊。编程语言就是这样,没有完美的东西,有所得必有所失啊。


(完)


1024肯定得有福利活动啊,2000个当当优惠码实付金额部分200减30,结算时输入优惠码:AREQDA,现在当当的很多书是满100减50,和优惠码可以叠加,想买书的要抓紧了!


另外,给码农翻身的读者报告一个好消息,当当网从科技+教育领域的几十万个图书品种中,精心挑选10个品质特别高的图书,作为当当20周年的主鉴品《码农翻身》有幸被选中。   说实话,从这么多书中被选中挺不容易的,也充分说明了《码农翻身》的品质。更详细的信息我会在以后的文章中发布。

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存