初识怪异的函数式编程
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); } }
这个函数很慢,因为它不断地调用自己,它还是个嗜内存魔,因为要持续分配对象。不过它的确是在用函数式风格。你可能会问,怎么有人会这样写程序?好的,后面会慢慢讲来。
相关文章推荐
- 函数式编程—初识Lambda表达式
- 函数式编程初识篇
- Java 中的函数式编程(Functional Programming):Lambda 初识
- webservice初识
- 【安卓网络请求开源框架Volley源码解析系列】初识Volley及其基本用法
- java初识之旅
- 初识三层架构
- 初识C++之函数重载、重写、重定义的区别
- 初识jenkins之-jenkins的使用
- 初识DocBook的一些经历
- Java Web基础知识之Servlet(1):初识Servlet
- [Servlet&JSP] 初识ServletContext
- Hadoop--初识Hadoop
- Hadoop初识--Hadoop单机模式安装和环境配置
- 杂七杂八话LTE(四十五):初识VoLTE
- node.js系列笔记之node.js初识《一》
- WPF从入门到放弃系列第一章 初识WPF
- 第一章 初识java
- 浏览器的标准模式与怪异模式
- DataBinding初识