博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
函数式编程另类指南1
阅读量:2395 次
发布时间:2019-05-10

本文共 3686 字,大约阅读时间需要 12 分钟。

程序员拖沓成性,每天到了办公室后,泡咖啡,检查邮箱,阅读 RSS feed,到技术站点查阅最新的文章,在编程论坛的相关版面浏览公共讨论,并一次次地刷新以免漏掉一条信息。然后是午饭,回来后盯了IDE没几分钟,就再次检查邮箱,倒咖啡。最后在不知不觉中,结束了一天。

不平凡的事是每隔一段时间会跳出一些很有挑战性的文章。如果没错,这些天你至少发现了一篇这类文章——很难快速通读它们,于是就将之束之高阁,直到突然你发现自己已经有了一个长长的链接列表和一个装满了PDF文件的目录,然后你梦想着到一个人迹罕至的森林里的小木屋苦读一年以期赶上,要是每天清晨你沿着那里的林中小溪散步时会有人带来食物和带走垃圾就更好了。

虽然我对你的列表一无所知,但我的列表却是一大堆关于函数式编程的文章。而这些基本上是最难阅读的了。它们用枯燥的学院派语言写成,即使在华尔街行业浸淫十年的专家(veterans也不能理解函数式编程(也写作FP)都在探讨些什么。如果你去问花旗集团(Citi Group)或德意志银行(Deutsche Bank)的项目经理[1],为什么选择了 JMS 而不 Erlang,他们可能回答不能在产业级的应用中使用学院派语言。问题是,一些最为复杂的,有着最严格需求的系统却是用函数式编程元素写成。有些说法不能让人信服。

的确,关于函数式编程的文章和论文难于理解,但他们本来不必这么晦涩。这一知识隔阂的形成完全是历史原因。函数式编程的概念本身并不困难。这篇文章可以作为简易的函数式编程导引。是一座从我们命令式(imperative)的思维模式到函数式编程的桥梁。去取杯咖啡回来继续读下去吧。可能你的同事很快就会开始取笑你对函数式编程发表的观点了。那么什么是函数式编程呢?它怎么产生?它可以被掌握吗(Is it edible)?如果它真如其倡导者所言,为什么没有在行业中得到更广泛的使用?为什么好像只有那些拿着博士学位的人才使用它?最要紧的是,为什么它就 TMD 这么难学?这些closure, continuation, currying,惰性求值和无副作用等等究竟是些什么东西?没有大学参与的项目怎么使用它?为什么它看上去这么诡异于和我们命令式思想友好,圣洁和亲近的一切的一切?我们将于不久扫清这些疑问。首先让我来解释形成实际生活和学界文章之间巨大隔阂的缘起,简单得像一次公园的散步。

 

信步游园

启动时间机器,我们散步在两千多年以前的一个被遗忘了太久的春季明媚的日子,那是公元前380年。雅典城墙外的橄榄树树荫里,柏拉图和一个英俊的奴隶小男孩朝着学院走去。天气真好饮食不错,然后话题开始转向哲思。

瞧那两个学生,为了使问题更容易理解,柏拉图仔细地挑选着用词,

你认为谁更高呢?

小男孩看着那两个人站着的水漕说,他们差不多一样高

柏拉图说:你的差不多一样是什么意思?我在这里看他们是一样

高的,不过我肯定如果走近些就会看出他们高度的差别。

柏拉图笑了,他正把这个孩子带到正确的方向。那么你是说,我们这

个世界没有完全的等同了?

小男孩想了一会儿回答,对,我不这样认为,任何事物总有一些区

别,即使我们看不到它。

这句话非常到位!那么如果这世上没有完全的相等,你又是如何理解

完全相等这个概念的呢?

小男孩迷惑得说:我不知道。最初尝试着理解数学的本源(nature

时也会产生这种疑惑。

柏拉图暗示这个世上的万物都只是一个对完美的近似。他还认识到我们即使没有接触到完美但依然可以理解这一概念。所以他得出结论,完美的数学形式只能存在于另一个世界,我们通过和那个世界的某种联系在一定程度上知晓他们。很明显我们不能看到完美的圆,但我们可以理解什么是完美的圆并用数学公式将它表达出来。那么,什么是数学?为什么宇宙可以用数学定理描述?数学可以描述宇宙中的所有现象吗?[2]

数学哲学是一个很复杂的课题。像大多数哲学学科一样它更倾向于提出问题而不是给出解答。这些意见中很多都循回绕转于一个事实,即数学实际上是一个谜语:我们设置了一系列基本的不冲突的原理和一些可以施加于这些原理的操作规则,然后我们就能堆砌这些规则以形成更复杂的规则。数学家把这种方法叫做形式系统演算。如果愿意,我们可以很快写出一个关于 Tetris(译者注:一种通常被称为俄罗斯方块的游戏)的形式系统。实际上,工作中的 Tetris 实现就是一个形式系统,只是被指定使用了个不常见的表现形式。

人马座的那个生物文明也许不能理解我们的 Tetris 和圆的范式,因为可能他们唯一的感知输入是气味香橙的橘子。他们也许永远不会发现 Tetris 范式,但很可能会有一个圆的范式。我们也可能将无法阅读它,因为我们的嗅觉没有那么复杂,可是一旦我们理解(pass)了那一范式的表示形式(通过这种传感器和标准解码技术来理解这种语言),其底层的概念就可被任何智能文明所理解。

有趣的是如果从来没有智能文明存在,Tetris 和圆的范式仍然严密合理,只是没有人注定将会发现他们。如果产生了一种智能文明,他就会发现一些形式系统来帮助描述宇宙的规律。但他还是不大可能发现 Tetris 因为宇宙中再没有和它相似的事物。在现实世界中这类无用的形式系统或迷题的例子数不胜数,Tetris 只是其中的一个典型。我们甚至不能确定自然数是否是对客观世界的完整近似,至少我们可以简单的想像一个很大的数它不能用宇宙中任何东西描述,因为它以近乎无穷。

 

历史一瞥[3]

再次启动时间机器,这一次的旅行近了很多,我们回到 1930 年代。大萧条正在蹂躏着那个或新或就的时代。空前的经济下挫影响着几乎所有阶层的家庭生活,只有少数人还能够保持着饥谨危机前的安逸。一些人就如此幸运地位列其中,我们关心的是普林斯顿大学的数学家们。

采用了歌特式风格设计建造的新办公室给普林斯顿罩上天堂般的幸福光环,来自世界各地的逻辑学家被邀请到普林斯顿建设一个新的学部。虽然彼时的美国民众已难能弄到一餐的面包,普林斯顿的条件则是可以在高高的穹顶下,精致雕凿的木质墙饰边上整日的品茶讨论或款款慢步于楼外的林荫之中。

阿隆左·丘奇就是一个在这种近于奢侈的环境中生活着的数学家。他在普林斯顿获得本科学位后被邀留在研究生院继续攻读。阿隆左认为那里的建筑实属浮华,所以他很少一边喝茶一边与人讨论数学,他也不喜欢到林中散步。阿隆左是一个孤独者:因为只有一个人时他才能以最高的效率工作。虽然如此,他仍与一些普林斯顿人保持的定期的联系,其中包括阿兰·图灵,约翰··诺依曼,和 kurt Grodel

这四个人都对形式系统很感兴趣,而不太留意现实世界,以便致力于解决抽象的数学难题。他们的难题有些共同之处:都是探索关于计算的问题。如果我们有了无限计算能力的机器,哪些问题可以被解决?我们可以使他们自动地得以解决吗?是否还是有些问题无法解决,为什么?不同设计的各种机器是否具有相同的计算能力?

通过和其它人的合作,阿隆左·丘奇提出了一个被称为 lambda 演算的形式系统。这个系统本质上是一种虚拟的机器的编程语言,他的基础是一些以函数为参数和返回值的函数。函数用希腊字母 lambda 标识,这个形式系统因此得名[4]。利用这一形式系统,阿隆左就可以对上述诸多问题推理并给出结论性的答案。

独立于阿隆左,阿兰·图灵也在进行着相似的工作,他提出了一个不同的形式系统(现在被称为图灵机),并使用这一系统独立得给出了和阿隆左相似的结论。后来被证明图灵机和 lambda 演算能力等同。

我们的故事本可以到此结束,我会就此歇笔,而你也将浏览到下一个页面,如果第二次世界大战没有在那时打响。整个世界笼罩在战争的火光和硝烟之中,美国陆军和海军前所未有的大量使用炮弹,为了改进炮弹的精确度,部队组织了大批的科学家持续地计算微分方程以解出弹道发射轨迹。渐渐意识到这个任务用人力手工完成太耗精力后,人们开始着手开发各种设备来攻克这个难关。第一个解出了弹道轨迹的机器是 IBM 制造的 Mark I —— 它重达5吨,有75万个组件,每秒可以完成三次操作。

竞争当然没有就此结束,1949年,EDVACElectronic Discrete Variable Automatic Computer,爱达瓦克)被推出并获得了极大的成功。这是对冯·诺依曼架构的第一个实践实例,实际上也是图灵机的第一个现实实现。那一年好运与阿隆左·丘奇无缘。

直到1950年代将尽,一位 MIT 的教授John McCarthy(也是普林斯顿毕业生)对阿隆左·丘奇的工作产生了兴趣。1958年,他公开了表处理语言 LispLisp 是对阿隆左·丘奇的 lambda 演算的实现但同时它工作在冯·诺依曼计算机上!很多计算机科学家认识到了 Lisp 的表达能力。1973年,MIT人工智能实验室的一组程序员开发了被称为Lisp机器的硬件-阿隆左 lambda 演算的硬件实现!

转载地址:http://ddzob.baihongyu.com/

你可能感兴趣的文章
Spring框架基础配置
查看>>
hibernate中持久化类的编写规则和主键生成策略
查看>>
HIbernate中持久化对象的三种状态
查看>>
HIbernate的一级缓存和快照
查看>>
HIbernate中的事务
查看>>
HIbernate--HQL举例+详解(一)
查看>>
HIbernate--HQL举例+详解(二)
查看>>
HIbernate--HQL举例+详解(三)
查看>>
Hibernate--Restrictions详解
查看>>
JSP--概述及运行原理详解
查看>>
JSP--脚本元素和注释
查看>>
JSP--指令(page、include、taglib)详解
查看>>
JSP--9个内置对象和4个作用域详解
查看>>
JSP--EL表达式详解
查看>>
JSP--JSTL标签库举例+详解
查看>>
Hibernate--QBC举例+详解(一)
查看>>
Hibernate--QBC离线查询举例+详解(二)
查看>>
Oracle11g--常用SQL命令(实用版)
查看>>
Oracle数据库体系结构
查看>>
Oracle--基本查询详解
查看>>