为什么“无人问津”的Lisp可以这么狂?

2019 年 5 月 23 日 码农翻身


一到周末,Hello World 咖啡馆就比平时热闹得多, 各种语言都来到这里,互相打探对方的最新特性,看看自己能不能借鉴一些。 


这天晚上,由于Lisp的到来,咖啡馆的气氛显得格外热烈。 


Lisp


Lisp身穿一身时髦又奇异的括号服装, 和Clojure, Scala等几个函数式编程的忠实拥趸坐在一桌,谈笑风声,时不时挖苦一下隔壁的几个人,那里坐着以C语言为首的几个大佬。 


他悠闲地端起了一杯咖啡,悠悠地说道:“听说Java也用上了函数式编程? ”


Clojure道:“是啊,加上去没多久,好多人还没用熟呢!”


Lisp不屑地说道:“加上了也没用,不是我瞧不起他们,表达能力实在是太弱了!”


隔壁的C语言早就憋了一肚子火, 听到这句话,忍不住说道:“你嘚瑟什么呀,我知道你是基于Lambda演算的,但我们是基于图灵机的啊, 上世纪已经证明这图灵机和Lambda演算是等价的,所以我们的能力是一样的。 对了,你知不知道什么是图灵机,以及他的实现冯诺依曼架构啊?”


Lisp懒懒地说:“没兴趣了解,理论上计算能力是等价的,但并不代表在语言层面的表示一样,比如说,在我这里非常自然的函数式编程,在你们那里看起来就很别扭,是不是啊Java老弟?” 


Java有点不好意思,他很清楚,自己的函数式编程就是一个半吊子,所谓的Lambda表达式就是个接口实现而已。

(详情参见:《Lambda表达式有什么用?》)


Python出来解围:“ 我这里支持得很好啊,  我可以把函数当做参数进行传递,可以把函数当做返回值返回,还可以把函数保存到数据结构中!高阶函数map, reduce用起来也贼爽。”


JavaScript接口道:“我也是啊!”


程序就是数据


Lisp 笑了一下,接着问道:“你们能在运行时创建新的函数吗?”


Java 看到展示自己的机会来了,马上接口道:“怎么不能? 在程序运行的时候,我可以通过操作Java字节码的方法,动态地生成函数和类,人们经常说的AOP就是这么玩的。”


Lisp很不屑:“还操纵字节码,还AOP,麻烦不麻烦!  低级不低级!丢人不丢人! ”


Java一脸愕然。


Lisp开始放大招: “你们能不能写个函数,把代码传递进去,然后对代码进行修改,然后返回新的代码?”


一个修改代码的函数?  代码可以在运行时修改? 这不是自虐吗?


“哈哈,这你们就不懂了吧, 凭什么数据结构可以变化,并且其中的数据可以修改,而程序却不能呢?在我这里,代码就是数据,代码可以在运行时被修改。”  Lisp很得意。


JavaScript愤愤地说:“这有什么鸟用?”


Lisp看了看身边的Java ,又拿他开刀:“就拿你来举例吧, 你最早只有for 循环,没有for each 循环, 就是下面这样, 是不是被很多人骂啊?”


普通for 循环

for(int i=0;i<persons.size();i++){
    Person p = persons.get(i);
    System.out.println(p);
}



for each 循环

for (Person p : perons){
     System.out.println(p);
}


Java无奈地点点头,Lisp说的是实话。


“这就是了,要想把这个新的语法给加上,那必须得在语言层面修改才行,对吧? 语言不支持,程序员骂也没用。 但是在我Lisp里就不一样了,根本就不用改动语言,一个程序员就能把这个新的语法给加上,并且新的for each 和 老的for 处于同等地位,相当于语言被扩展了。 ”


“不会吧,你怎么实现?” 


“自然是使用宏(Macro)了!”


“什么是宏? 和C老大的宏一样吗?” Java问道。


“C语言的宏就是编译期的文本替换而已,怎么能和我的宏相比? 给你说你也听不懂,通俗点说宏也是程序员写的代码, 运行时可以把代码传递给宏,然后宏可以修改这段代码,返回新的代码。 拿刚才的例子来说,假设for是个函数,程序员可以写一个for-each 的宏,在这个宏中,修改/扩展for函数的代码,实现for each的功能。”


C语言若有所思:“嗯,看来在你这里,程序也是数据啊,可以任意操作,果然厉害。如果把一段程序看成是抽象语法树(AST),那这个宏就相当于把AST做了修改,形成了新的AST。”



Lisp心想,这老家伙还不赖, 已经Get到了。  


他说:“你们老是笑话我的括号多,但是你们不明白的是,这恰恰是我最大的优势,因为在我这里,数据和程序表示的方式是一致的,都是list,比如这一段简单的循环。”


(loop for x in '(1 2 3 4 5)
      do (print x) )


大家一看,果然如此,这代码(loop函数)是用括号括起来的一个List, 这数据(1 2 3 4 5)也是一个List。


Lisp说:“List的好处就是天然可以和AST对应,这就方便宏来操作了。”



开发语言的语言


JavaScript说:“我还是看不出有什么用?”


Lisp接着说:“正是由于程序可以当做数据来处理,程序员可以无限地扩充Lisp,把Lisp变成他们所在领域的语言,使用这个领域特定的语言来编程,那简直是如虎添翼,例如这个例子,通过扩展Lisp,   Lisp和SQL语言完美地融合了。 ”


(select [age] :from [employee] :where [> [salary] 50000])


“再比如说, 在座的各位大都支持面向对象编程,对我来说,在我这里实现OOP也是小菜一碟,比如Common Lisp中的CLOS,就是用宏实现的OOP操作集。”


大家都表示很好奇, Lisp就展示了几行代码:


定义一个叫Person的类

(defclass person ()
  ((name :accessor person-name
           :initarg :name)
   (age :accessor person-age
           :initarg :age)))



创建一个person对象

(setf p (make-instance 'person :name "andy" :age 10))



访问对象的属性

(print (person-name p))


看到这里,大家都自愧弗如了, 这Lisp真有狂的资本啊。 


C 语言说到:“看来你Lisp是用来开发其他语言的语言啊!”


Lisp笑道:“这句话不错,在我这里,语言和程序之间的界限是非常模糊的。”


最后的反击


C语言问了最后一个问题:“既然你这么牛? 为什么用的人这么少?”


Lisp站起身来,叹了一口气:“有人说学起来门槛太高;有人说灵活与强大是一把双刃剑,每个人都能造属于自己的领域特定语言,让别人难以理解和维护;还有人说Lisp方言很多,社区分裂,没有统一的库让新手学习使用。 谁知道呢?”


说完Lisp便离开了,只留下一个满是括号的背影。


最新 热门文章

为什么学习编程要从Web开始?

我是一个线程

我是一个Java Class

CPU阿甘

面向对象圣经

TCP/IP之大明邮差

负载均衡的原理

一个故事讲完HTTPs

编程语言的巅峰

JavaScript:一个屌丝的逆袭

登录查看更多
0

相关内容

高阶和符号计算是一本国际期刊,它提供了一个广谱论坛,讨论高阶和符号设施编程的结果和思想:一级函数和延续、效果和高阶类型、对象、参与者和数据程序。内容包括从理论和设计到实践和经验的论文,尤其是实践中使用的理论。该杂志促进具有广泛兴趣和专业知识的研究人员之间的思想交流和协同作用。覆盖范围包括带效果的函数编程;面向对象编程;并行、并发、分布式和移动符号和函数计算;编程概念和抽象-数据抽象、延迟计算、无限数据对象、自引用、反射、连续、组件、通用函数,继承、封装、保护、持久性、元对象、通信协议等等。官网链接:https://link.springer.com/journal/10990
【2020新书】实战R语言4,323页pdf
专知会员服务
98+阅读 · 2020年7月1日
【Manning新书】现代Java实战,592页pdf
专知会员服务
98+阅读 · 2020年5月22日
【实用书】Python技术手册,第三版767页pdf
专知会员服务
229+阅读 · 2020年5月21日
Python导论,476页pdf,现代Python计算
专知会员服务
253+阅读 · 2020年5月17日
【实用书】Python爬虫Web抓取数据,第二版,306页pdf
专知会员服务
115+阅读 · 2020年5月10日
【2020新书】C++20 特性 第二版,A Problem-Solution Approach
专知会员服务
57+阅读 · 2020年4月26日
Python数据分析:过去、现在和未来,52页ppt
专知会员服务
99+阅读 · 2020年3月9日
说说我的老同事,前端大神程劭非
余晟以为
17+阅读 · 2019年1月14日
程序猿的终极噩梦,祖传代码,一动,修半年!
九章算法
4+阅读 · 2018年12月20日
一天精通无人中级篇:遥控器协议 S-BUS
无人机
48+阅读 · 2018年12月20日
Flink 靠什么征服饿了么工程师?
阿里技术
6+阅读 · 2018年8月13日
Python为啥这么牛?
Python程序员
3+阅读 · 2018年3月30日
为什么你应该学 Python ?
计算机与网络安全
4+阅读 · 2018年3月24日
传说中的马尔科夫链到底是个什么鬼?
R语言中文社区
6+阅读 · 2018年2月27日
5年开发老鸟转型人工智能心酸史
算法与数据结构
4+阅读 · 2017年11月13日
十五条有用的Golang编程经验
CSDN大数据
5+阅读 · 2017年8月7日
Arxiv
4+阅读 · 2018年9月25日
Relational recurrent neural networks
Arxiv
8+阅读 · 2018年6月28日
Arxiv
6+阅读 · 2018年2月6日
Arxiv
5+阅读 · 2018年1月30日
Arxiv
26+阅读 · 2017年12月6日
VIP会员
相关VIP内容
【2020新书】实战R语言4,323页pdf
专知会员服务
98+阅读 · 2020年7月1日
【Manning新书】现代Java实战,592页pdf
专知会员服务
98+阅读 · 2020年5月22日
【实用书】Python技术手册,第三版767页pdf
专知会员服务
229+阅读 · 2020年5月21日
Python导论,476页pdf,现代Python计算
专知会员服务
253+阅读 · 2020年5月17日
【实用书】Python爬虫Web抓取数据,第二版,306页pdf
专知会员服务
115+阅读 · 2020年5月10日
【2020新书】C++20 特性 第二版,A Problem-Solution Approach
专知会员服务
57+阅读 · 2020年4月26日
Python数据分析:过去、现在和未来,52页ppt
专知会员服务
99+阅读 · 2020年3月9日
相关资讯
说说我的老同事,前端大神程劭非
余晟以为
17+阅读 · 2019年1月14日
程序猿的终极噩梦,祖传代码,一动,修半年!
九章算法
4+阅读 · 2018年12月20日
一天精通无人中级篇:遥控器协议 S-BUS
无人机
48+阅读 · 2018年12月20日
Flink 靠什么征服饿了么工程师?
阿里技术
6+阅读 · 2018年8月13日
Python为啥这么牛?
Python程序员
3+阅读 · 2018年3月30日
为什么你应该学 Python ?
计算机与网络安全
4+阅读 · 2018年3月24日
传说中的马尔科夫链到底是个什么鬼?
R语言中文社区
6+阅读 · 2018年2月27日
5年开发老鸟转型人工智能心酸史
算法与数据结构
4+阅读 · 2017年11月13日
十五条有用的Golang编程经验
CSDN大数据
5+阅读 · 2017年8月7日
Top
微信扫码咨询专知VIP会员