代码改变世界

周末话题-函数编程

2008-08-02 09:43  横刀天笑  阅读(2125)  评论(17编辑  收藏  举报
C# 3.0中加入的新特性中,最大头的一个就是Lambda表达式,微软利用这个Lambda表达式结合其它一些特性演绎了很多东西,Lambda表达式和扩展方法一起带来了Linq to Objects,从Lambda表达式推演出来的表达式树又是Linq to SQL等的基础。就在C#“”之时,还有另一门语言在悄悄崛起:F#,微软不久前宣布,F#将进入产品阶段,也就是到了下一个版本,F#将和C#,VB.NET平起平坐了。而Lambda表达式和F#都归属于函数编程范畴,今日的话题就以函数编程为线吧。

 

伟大的邱奇和他的Lambda演算

 

我们肯定都知道冯.诺依曼,因为他是计算机之父,因为他的.诺依曼体系结构。我们肯定都知道阿兰.图灵,人工智能之父,著名的图灵奖堪称计算机业的诺贝尔。在这个时代还存在另外一个传奇人物:阿隆左·丘奇(Alonzo Church),知道这个人的请举手,反正我是很晚才知道。

1936年,图灵的一篇论文:论数字计算在决断难题中的应用,在这篇论文中,提出了图灵机的设想,这也是今天计算机的基础,因为他不仅仅提出了设想,还在理论上证明了这种机器是可以制造出来的,不过在这之前,还有一个Lambda演算的理论,该理论奠定后来的Lisp语言(值得注意的是,Lisp是我们拥有的第二个计算机高级语言,仅次于Forton之后)和函数编程的基础。

 

函数编程是无状态的,还没有变量?

 

虽然我们整天说,计算机是建立在数学上的一门学科,但感触却不是很深,因为今天我们所使用的机器,语言无不是以图灵机为基础的,图灵机虽然也是数学的结晶,但我觉得还是带有机械运动的色彩在里面,而函数式编程却原原本本就是数学。

函数式编程利用数学上的函数来避免状态(这个可是图灵机的基础,图灵机利用状态去判定下一步工作,而函数式编程却不需要状态)和可变的数据(今天,如果没有变量,我真的不知道我该怎么编写代码)。看起来非常的奇妙,但这一切都是Lambda演算赐予的。

 

Lambda演算

 

那啥事Lambda演算呢?起这么一个奇怪的名字。在数理逻辑里,Lambda(λ)演算是用来研究函数的定义,函数应用和递归的。在Lambda演算里,用一元函数(只有一个输入,一个输出的函数)表示所有的表达式,而这个函数的参数和返回值都是表达式(也都是一元函数了),Lambda演算里使用Lambda表达式表示匿名的函数,这个和.net里是一样的,比如:f(x) = x+2;这个表示为 λx.x+2,也可以表示成λy.y+2,参数名字是无关紧要的。f(3)就可以表示成(λx.x+2)3。那f x y = f(x)y,这样看,有多个参数的函数可以用这样的Lambda演算表示:一个一元函数的返回值作为另外一个一元函数的参数,一种递归的定义。

我们来看看怎样用上下文无关文法(参考编译原理内相关内容)来定义这个Lambda演算:

1.   <expr> ::= <identifier>

2.   <expr> ::= (λ <identifier> . <expr>)

3.   <expr> ::= (<expr> <expr>)

上面的定义清楚的表明Lambda演算是一个递归的定义。

函数式编程

 

本来,我也想多搜寻一些关于函数编程的资料,无奈,知识匮乏,搜寻到的资料很多地方大脑转不过弯来。所以这里我就留下空白,希望大家能发表自己对函数编程的一些看法,如果你像我一样并不是很了解函数编程,希望本文能给你一些开端,如果你已经是函数编程的高手,希望你能够在评论里留下你的足迹,谢谢。

 

 

祝你编程愉快