关于λ经常会听到λ演算和λ表达式这两名词,其实分别对应的是理论和应用两个维度。它们的关系可以类比于质能方程和原子弹。
λ演算
数学家阿隆佐-邱奇在20世纪30年代提出λ演算,作为数学基础研究的一部分。那个年代,数学界有个领袖,叫希尔伯特(一人之力将葛根廷大学建设为当时数的世界中心)。他提出将数学定理机械化,这样机器就可以通过形式语言推理出大量新定理(AI的味道?)。比他小几岁的图灵和邱奇都受到他这一思潮影响,并从不同的角度解决了这同一个问题。理论上,图灵机和λ演算,都可以模拟出我们今天所有的程序。
λ演算是一种形式系统(formal system),什么是形式系统呢?大家知道,数学语言是是可以脱离现实而存在的——大家把数学想成了一种符号游戏,脱离生活常识,从公理开始,进行大量的推导和证明——最终产生一个系统,里面有公理、定理、推论、猜想…上述这种自成体系,有公理又有推理证明方法的体系,称为形式系统。而形式系统需要语言去描绘,这种语言就是形式语言(formal language)。邱奇希望用λ演算来表达有关数学的一切,比如用一系列函数来表达自然数,符号,定理等。
本质上图灵机和λ演算是做同一件事情,也是可以互相转换的。
Lambda表达式
区别于λ演算中的λ表达式,编程中提到的Lambda表达式,一般就指一个匿名函数。为什么要用匿名函数,对于一个只用一次的函数,匿名使用当然更简洁方便。eg,给view一个点击事件:
1 | // java 8以前 |
那种写法更好一目了然,对吧。
所以在编程中使用Lambda表达式,可以让代码更符合直觉,写法清晰简练自然也带来更好的维护性。
好的维护性程序员不挠头,也可以推导出Lambda表达式具有程序员发际线友好特性。
λ与编程语言
图灵机奠定了计算机基础,那能和它等价转化的λ演算呢?实际上λ演算在数学、哲学[2]、语言学[3][4]和计算机科学[5]中都有许多应用。它在编程语言理论中占有重要地位,函数式编程实现了λ演算支持。λ演算在范畴论中也是一个研究热点。
大部分编程语言都或多或少受λ演算所启发和影响,尤其是函数式友好语言(Lisp,ML,Haskell,Scala,C++,Java8 Lambda)。
Java8 实现Lambda的方式是通过invokedynamic指令,运行时调用LambdaMetafactory.metafactory动态的生成内部类,在内部类里调用原class的静态方法快来实现的。
应用
在Java中能被Lambda改写的前提必须是一个函数接口(指内部只有一个抽象方法的接口)。
1 | @FunctionalInterface |
上面代码中的@FunctionalInterface不是必须而是可选的,但加上该标注编译器会帮你检查接口是否符合函数接口规范。就像加入@Override标注会检查是否重载了函数一样。
1 | //1,点击事件 |