您的位置:首页 > 编程语言

初识怪异的函数式编程

2013-07-02 00:00 162 查看

函数式编程

函数式编程是对阿隆佐·丘奇理论的实践应用。但也并非全部 λ 演算都被应用到了实践中,因为 λ 演算不是被设计为在物理局限下工作的。因此,和面向对象的编程一样,函数式编程是一系列理念,而不是严格的教条。

现在有很多种函数式编程语言,他们中的大多数以不同方式完成不同任务。在这里我对最广泛使用的源自函数式编程的思想作一解释,并将用 Java 语言举例(是的,你完全可以用 Java 写出函数式程序,如果你有显著的受虐倾向)。在下面的小节中,我将会把 Java 作为一种函数式语言,并对其稍加修改使它成为一种可用的函数式语言。现在开始吧。

λ 演算被设计用来探询关于计算的问题,所以函数式编程主要处理计算,并用
函数
来完成这一过程。函数是函数式编程的基本单位,函数几乎被用于一切,包括最简单的计算,甚至变量都由计算取代。在函数式编程中,变量只是表达式的别名(这样我们就不必把所有东西打在一行里)。变量是不能更改的,所有变量只能被赋值一次。用 Java 的术语来说,这意味着所有单一变量都被声明为 final(或 C++ 的 const)。在函数式编程中没有非 final 的变量。

final int i = 5;
final int j = i + 3;

因为函数式编程中所有变量都是 final 的,所以可以提出这样两个有趣的表述:

没有必要总是写出关键字 final。

没有必要把变量再称为变量。

于是现在我们对 Java 作出两个修改:在我们的函数式 Java 中所有变量默认都是 final 的,我们将变量(variable)称为符号(symbol)。

你也许会质疑,用我们新创造的语言还能写出有些复杂度的程序吗?如果每个符号都是不可变更(non-mutable)的,那么就无法改变任何状态!其实事实并非完全如此。在阿隆佐研究其 λ 演算时,他并不想将某个状态维护一段时间以期未来对其进行修改。他关注的是对数据的操作(也通常被称为“演算体 caculating stuff”)。既然已经证明 λ 演算与图灵机等价,它可以完成所有命令式编程语言能够完成的任务。那么,我们怎么才能做到呢?

答案是函数式程序能保存状态,只是它并非通过变量而是使用函数来保存状态。状态保存在函数的参数中,保存在堆栈上。如果你要保存某个状态一段时间并时不时地对其进行一些修改,可以写个递归函数。举个例子,我们写个函数来翻转 Java 的字符串。记住,我们声明的每个变量默认都是 final 的。

String reverse(String arg) {
if(arg.length == 0) {
return arg;
}
else {
return reverse(arg.substring(1, arg.length)) + arg.substring(0,1);
}
}


这个函数很慢,因为它不断地调用自己,它还是个嗜内存魔,因为要持续分配对象。不过它的确是在用函数式风格。你可能会问,怎么有人会这样写程序?好的,后面会慢慢讲来。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: