柯里化的前生今世(二):括号神教

The limits of your languages are the limits of your world.
只会一种语言,会限制你的视野,很难有机会去接触那些有趣的想法。
语言是表达思想的工具,而有想法的人未必用我们熟知的语言去表达。
所以,我们就不得不多学一些。

关于

在上一篇中,我们提到了著名的逻辑学家Haskell Curry,
提到了类型和函数,以及看待多元函数的不同方式。
最后,引出了curry和uncurry两个高阶函数。

为了理解高阶函数,以及相关的,求值环境,词法作用域,闭包等概念。
我们从今天起要学习一门新的语言了,用它来描述这些概念比较方便。
过几天,当我们遇到参数化类型,代数数据类型的时候,
我们会再学一门语言。

括号神教

今天我们要学习的语言是Racket,它是Lisp家族中的一个语言。
Lisp,最初被拼为LISP,一个历史悠久的编程语言家族。最早由约翰·麦卡锡在1958年基于λ演算创造,演化至今,是历史第二悠久的高级语言,仅次于Fortran,也是第一个函数式编程语言。

约翰·麦卡锡

约翰·麦卡锡(John McCarthy,1927-2011),生于美国马萨诸塞州波士顿,计算机科学家。他因在人工智能领域的贡献而在1971年获得图灵奖。
他于1948年获得加州理工学院数学学士学位,1951年获得普林斯顿大学数学博士学位。分别短暂地为普林斯顿大学、斯坦福大学、达特茅斯学院和麻省理工学院供职后,麦卡锡于1962年-2000年底在斯坦福担任教授,退休后成为名誉教授。

最美丽的传说

在ILC 2002大会上前Lisp大神,当今的Python倡导者Peter Norvig,由于某些原因,做一个类似于马丁路德在梵蒂冈宣扬新教的主题演讲,因为他在演讲中大胆地声称Python就是一种Lisp。
讲完后进入提问环节,出乎我意料的是,Peter点了我过道另一侧,靠上面几排座位的一个老头,他衣着皱褶,在演讲刚开始的时候踱步进来,然后就靠在了那个座位上面。
这老头满头凌乱的白发,邋遢的白胡须,像是从旅行团中落下的游客,已经完全迷路了,闲逛到这里来歇歇脚,随便看看我们都在这里干什么。我的第一个念头是,他会因为我们的奇怪的话题感到相当失望;接着,我意识到这位老头的年纪,想到斯坦福就在附近,而且我想那人也在斯坦福 —— 难道他是……

“嗨,John,有什么问题?” Peter说。
虽然这只是10个字左右的问题,我不会假装自己记住了Lisp之父约翰·麦卡锡说的每一个字。他在问Python程序能不能像处理数据一样,优雅地处理Python代码。
“不行。John, Python做不到。”
Peter就回答了这一句,然后静静地等待,准备接受教授的质疑,但老人没有再说什么了。
此时,无语已胜千言。

Realm of Racket

Lisp家族

跟其他语言不同的是,Lisp语言是一个家族,它的成员被称之为“方言”。
大部分方言都鲜有人知,例如Arc语言,由《黑客与画家》的作者Paul Graham发明。
市面上流行的方言,包括以下几个,
1. Elisp,是Emacs编辑器支持的脚本语言,可以用elisp扩展Emacs的功能。由于lisp方言强大的表达能力,以及Emacs优雅的架构,让Emacs获得了“神之编辑器”的称号。
2. Clojure,运行在JVM上的另一种语言,Java是另一种。Clojure对并行和并发的支持,有自己的方式,在并发方面上,它没有提供线程和锁,而是提供了其他4种方式,Vars, Refs, Agents and Atoms
3. Common Lisp,是商业级的Lisp方言,规范长达1000多页。有LispWorksAllegro CL这些强大的IDE。Common Lisp不支持hygienic macro,在编写宏的时候,容易出现意外的捕获。不过,这也增加了灵活性和表现力。除此之外,Common Lisp还支持Reader macro,和Racket的#reader有异曲同工之妙。
4. Scheme,是一门力求简洁的Lisp方言,它首次提出了闭包的概念,提出了first-class continuation,提出了hygienic macro,然而它最新的R7RS规范包括最后的附录才只有88页。

DrRacket


Racket,原名PLT Scheme,在Scheme基础上增加了对象、类型、惰性求值等。
它提供了一个IDE,成为Docdor Racket,简称DrRacket,自带丰富的第三方库,如web服务器、数据库、GUI、图像处理等。

我们可以通过Racket的官网,找到DrRacket的下载地址,可以找到多个平台相应的安装包,windows和linux,osx都支持。

安装后,我们打开DrRacket,玩一下。
犹记得去年情人节,DrRacket还卖萌了一把,把图标变成了心形。

打开后,IDE的界面如下,由上下两部分构成,
上面那块称为定义区(definitions panel),下面称为交互区(interactions panel)。

以上,就是标准的Hello world实现了,当然它不仅仅是个玩具哦。

预知后事如何,且听我下回分解。

参考

LISP
约翰·麦卡锡
至今听到关于Lisp最迷人的故事
Realm of Racket
The Racket Reference

时间: 2024-11-08 19:00:54

柯里化的前生今世(二):括号神教的相关文章

柯里化的前生今世(一):函数面面观

关于 本文作为开篇,介绍了出场人物,并形象化的引入了高阶函数, 得到了柯里化的概念. 后续文章,会介绍高阶函数的实现方式,词法作用域和闭包,参数化类型,类型上的柯里化, 敬请期待. 如有不同的认识,或者感兴趣的点,请直接联系我,欢迎指教. 人物介绍 球星库里 库里,Stephen Curry,1988年3月14日出生于美国俄亥俄州阿克伦(Akron, Ohio), 美国职业篮球运动员,司职控球后卫,效力于NBA金州勇士队. 斯蒂芬·库里2009年通过选秀进入NBA后一直效力于勇士队,新秀赛季入选

柯里化的前生今世(八):尾调用与CPS

关于 在上一篇中,我们介绍了continuation的概念,还介绍了Lisp中威力强大的call/cc,它提供了first-class continuation,最后我们用call/cc实现了python中的generator和yield. call/cc赋予了我们很强的表达能力,Lisp中的异常处理机制也很人性化. 例如,Common Lisp: Condition_system, 由于call/cc可以捕捉到异常处的continuation, 我们就可以手动调用这个continuation,

柯里化的前生今世(十二):多态性

关于 本文借用Haskell介绍了自定义类型,带参数的类型,Ad-hoc多态性,kind, 其中,带参数的类型在类型上可以做"柯里化". 1. 自定义类型 Haskell中使用data自定义类型. data Bool = True | False 其中,Bool是类型名,True和False是该类型的值. 一个值可以包含多种不同类型的字段(field),例如, data BookType = BookValue Int String 其中BookType是类型名,BookValue是值

柯里化的前生今世(四):编译器与解释器

关于 在上一篇中,我们提到了形式语言与文法,S表达式与M表达式,同像性. 本文将开始写一个简单的解释器, 通过具体实现,我们来理解求值环境,动态作用域和静态作用域,还有闭包等概念. 当然,一篇文章来写完这些肯定是不够的,我们可以慢慢来,循序渐进. 写完了这个解释器之后,我们会增加一些新的功能. 编译器与解释器 编译器会将源代码转换成另一种语言的代码,然后在支持后一种语言的机器上执行. 而解释器则不同,它会逐行分析源代码,直接执行分析结果. 值得一提的是,编译和解释是执行代码的两种手段, 具体的语

柯里化的前生今世(九):For Great Good

关于 上文第二~八篇中,我们学习了Racket语言,它很有代表性,是一种Lisp方言. 很多概念用Racket描述会更加简便. 我们介绍了高阶函数,词法作用域,闭包以及continuation, 这些概念对理解函数式编程来说十分重要. 然而,偏见却经常起于片面. 只学习一种语言,会让我们对事物的同一个侧面产生习惯. 事实上,我们需要多样化的角度,也需要经常更换思维方式. 这对学习新知识很有帮助, 有些时候,我们理解不了某些概念,很有可能是因为这个概念被描述的不够全面, 我们经常走到深入思考这一特

柯里化的前生今世(十):类型和类型系统

形式化方法 在计算机科学中,尤其在软件工程和硬件工程领域, 形式化方法(Formal method),是一种数学方法,用于软件和硬件系统的描述(specification).开发(development)和验证(verification).旨在能像其它工程学科一样,通过用数学进行分析,来提高设计的可靠性(reliability)和健壮性(robustness). 为了让系统表现的和规范(specification)一致,现代软件工程采用了一系列的形式化方法.其中包括一些强有力的框架,例如,霍尔逻

柯里化的前生今世(十一):Pure and Lazy

语言的作用 语言可以用来交流想法,描述概念, 当前使用了什么语言,取决于我们有什么样的需要. 为了理解词法作用域,闭包,和continuation, 前文中,我们借助了Racket. 现在,为了理解代数数据类型(algebraic data type),多态(polymorphism),参数化类型(parameterized type),类型类(type class),我们要学习Haskell了. 编程也是如此,它是关于思想的, 编程语言只是描述这种思想的工具罢了. 非严格语义(non-stri

柯里化的前生今世(三):语言和同像性

按照故事情节的正常发展,我们这一篇该介绍Racket语言的语法了. 可是,在大局观上,我们还没有达成共识. 对于一个概念来说,我们不止要学会怎样描述它,还要学会理解它的内涵. 因此,这篇还是在打基础,俗称,引言.. 关于 在上一篇中,我们提到了Lisp语言家族,看到了关于Lisp最美丽的传说,我们提到了Racket,以及它的IDE,DrRacket. 本文将从目标语言和元语言,同像性(Homoiconicity),引用等这些角度来深入的讨论Lisp, 浅尝辄止,毕竟不是一个好习惯. 目标语言和元

柯里化的前生今世(十三):WHNF

1. 形式系统(Formal system) 在逻辑学与数学中,一个形式系统由两部分组成,一个形式语言加上一套推理规则. 一个形式系统也许是纯粹抽象地制定出来的,只是为了研究其自身. 也可能是为了描述真实现象或客观事实而设计的. 2. λ演算(λ-caculus) λ演算用于研究函数定义.函数应用和递归,它是一些形式系统的总称, 配备不同的推理规则集,就会得到不同的演算系统. λ演算由Alonzo Church和Stephen Cole Kleene在20世纪三十年代引入, Church在193