[学习] 从 函数式编程 到 lambda演算 到 函数的本质 到 组合子逻辑
函数式编程
阮一峰 《函数式编程初探》,阮一峰是《黑客与画家》的译者。
wiki 《函数编程语言》
一本好书,《计算机程序的构造与解释》有讲到scheme lisp, 不过是作为工具。重点还是再讲方法论,虽然只看了前言,已经觉得是非常好的书,非常有高度。
写这段话的人叫 艾伦佩利。他为这本书做的序,写的更好。非常有高度,非常有智慧,即使不读这本书,也推荐读一下序。
《解释》是作为MIT的课程教材。其中提到了另一门课 6.231 可以作为该可的前导学习。也对应了一本英文版的教材《dynamic programing and Optimal control》,不过我没看,也没有列入计划。
lambda演算
0
我试图想要总结或者抄录一句话来定义,什么叫lambda演算,遗憾的是没有成功找到一句简洁又明晰的。如果一定要找一个的话,可能是这样的:
1
一篇轻松又好读的译文:
2
函数式编程的重要性在于lambda演算,而lambda演算则牵扯到了数学和公理体系。
理解函数式编程最重要的是理解什么是lambda演算,理解lambda演算最重要的是理解什么是函数,以及什么是高阶函数。
见 <<lambda.pdf>>
柯里化:把任意多参数函数都转换成单参数的高阶函数。
个人理解:原来一切都是从lambda运行演进出来的,数据结构,谓词,逻辑操作,Ture,False,运算符。不过细节都没有认真的读。比较学术,应该好好读一下。
所以,整个函数式编程世界里的一切,都是基于lambda演算的定义,已经基于这个定义的推演组成的。
说一个不准确的类比,整个数学世界都是通过自然数和加法演化出来的。而自然数是通过数字0和加一函数演化出来的。我们可以理解成:0和加一的定义,就是lambda演算的定义。
函数的本质
函数的本质——组合子逻辑入门
仅用高中数学的知识,便讲清楚了这个概念,特别好读。
摘录:
组合子,其实就是由某些最简单的函数经过各种有限次“组合”方法形成的具有固定语义的函数。举一个极端点的例子,乘法函数,*(x,n),可以看做是加法函数+(x x)的n此叠加,因此可以看做是一个组合子。
组合子理论,将函数看做是所有概念、定义、公理和定理的最基本元素。从函数角度来看,所谓概念,无非就是再没有变项可以完全确定的(completely determined)常项函数;而公理,就是一个函数值为永真的命题函数;
而推理,就是将这些代表概念、公理的函数做各种组合生成新的函数,它们命题真值也必须为真。
说:学习λ而不学习CL是不完整的学习。历史上CL是原创,λ是在CL的基础之上的变种。
CL是指 combinatory logic 也就是 组合子逻辑
《通往逻辑、数学和编程的Haskell之路》—— 函数
这几篇内容都是《The Haskell Road to Logic, Maths and Programming》的读书笔记。
摘录:
如果有人让你用简单一句话说明数理逻辑和普通逻辑有什么本质不同,你该怎么说呢?回答就是:数理逻辑有函数,而普通逻辑没有。
既然逻辑的形式本质上就是函数,那么,对逻辑学的研究其实就是对函数的研究。
逻辑学由于插上了函数的翅膀才可以催生、演变为计算理论——可计算函数的研究,它的实质就是计算机科学最本质的问题:可计算性问题和计算复杂性的研究。
所谓lambda-演算,就是把函数的研究进一步抽象化,研究函数的的抽象形态、抽象形态对具体值的应用,以及函数值的最终的“实现”——β-归约。
后来甚至有人把函数的概念推广到了哲学。所以从某个程度、某个方面来说,20世纪的形式科学就是函数的科学,函数,已经成为学习计算机科学、数学、逻辑学、语言学和哲学的跨学科的共同语言。
有了函数,无论是数学、逻辑、自然语言都可以用这种统一的方式表达,这就是我们为什么要用编程语言、用Lisp、Haskell表示逻辑的最基本动机和理由。 因此,熟悉这两种语言、进而熟悉它们的通用形式化表达——lambda-演算的关键,就是对函数概念的透彻理解,这里面包含了三个层次:
(1) 函数的内涵表达式——抽象;
(2) 函数符号和参数的关系——应用;
(3) 函数的代入求值。
最后,函数的外延表达式:有序对的集合和外延性原理。因为(3)的理论基础就是基于外延性原理的可替换原则。
如果对函数有了透彻的理解,你获得了一种洞见,洞若观火之见,那就是,逻辑和计算是一回事,是一个统一体的两个侧面。
《通往逻辑、数学和编程的Haskell之路》—— 从逻辑走向计算(1)
摘要:
而计算机科学,未来的人们会认识到它的实质实际上是形式化“过程”(process)的知识:概念创建、实现和完成的过程,这种知识的本质就是:如何“证实”(verify)真理?计算机科学的任务就是精确阐述某个知识的实现方法。
我们要真正理解逻辑和计算的本质,基本上就像Abelson教授所述,一种是陈述性知识,一种是过程性知识,这两种知识的关联,就在于如何将陈述性知识转换为过程性知识。这是我们理解逻辑和计算关系本质的核心思想。
对函数的形式化研究早在上世纪1920年代就开始了,经Schönfinkel、Curry和Church,终于发展出两个平行但是又互补的学科——lambda演算和组合子逻辑。因此在我们真正开始学习用编程理解逻辑时,就要对这两个领域有所了解。
如果你是程序员,或者在读和信息科学、数学科学有关专业,那这两个学科知识的重要性不言而喻,你可能知道得更多。由于无论lambda演算还是组合子逻辑、再到类型论,其中心思想都是逻辑与计算的关系问题。
todo:
组合子逻辑、λ演算的历史背景和产生动机
组合子逻辑和λ演算属于数理逻辑中的形式系统,本质上是以函数为基本元素的高阶逻辑。
在这个意义上,如果要想真正搞懂它们的基本思想而不仅仅是编程等实用目的,就必须从一阶逻辑开始,而要真正透彻理解如何从一阶逻辑走到组合子逻辑、λ演算,就需要了解这两门学科产生的背景和动机,来龙去脉和前世今生。这也是本篇笔记的目的。
那么什么是【高阶函数】?简单武断地说就是:以函数作为参数的函数就是高阶函数。
因此λx.y的正确解读应当是表达式y中变量x的抽取——抽象化,表示变量x与表达式y内某一变量的互动关系。
现代形式科学的所有的故事都来自于莱布尼茨的两大梦想:第一、建立一套严格精密的人工语言,这种语言没有人类语言的歧义多结构,可以精确地描述任何哲学、逻辑和数学问题;
第二、找到一种方法,利用这套“普遍语言”,解决任何科学、哲学和数学的问题。
莱布尼茨的梦想,在20世纪先后成真:集合论和符号逻辑、计算科学。而这一切的一切都源自19世纪末20世纪初发生的第三次数学危机。
这场危机的结果使得数学、逻辑学和哲学发生了脱胎换骨的变化,数学的公理化、逻辑学的数学化、哲学的逻辑化是这个伟大变革中最显著的特点。
弗雷格、罗素、怀特海已经做了大量工作,在《Principia Mathematica》(数学原理)中,已经将定义前的逻辑运算符从五个减少到两个:否定和析取,或者,
否定和合取、析取、蕴含中的任何一个;在此基础上,波兰犹太裔的美国逻辑学家Henry Sheffer提出了一个最激进的简化方案,
单一逻辑运算符,写作:nand(学过逻辑电路的可能比较熟悉,称作“非与”门),逻辑符号用竖线表示:“|”,所以又称作“Sheffer竖线”(Sheffer Stroke),
其意义相当于合取运算的否定,~(𝑝 ∧ 𝑞),作为单一运算符,这样,所有其它运算符都可以从它派生。
这就是λ演算脱胎于逻辑,在数学基础研究遭遇失败后,成功转型成为早期理论计算科学基础的过程。
TODO:
再往后的内容,已经读不懂了,以后有机会再读。
https://site.douban.com/145723/widget/notes/192785890/note/609904895/
不完整的鸣谢,因为公开资料,很难追溯作者。
赛义甫。前文一部分读书笔记的作者。