对函数式编程的误解

jopen 12年前

 最近,我偶然看到了这样一篇文章:实用的纯函数式编程,里面谈到了函数式编程的优势。然而,作者的某些对函数式编程的思想认识却让我诧异:

“长期的处在命令式编程的环境世界里会让我们养成一种特定的顺序式的思考方式 … 而另一边,在纯函数的世界里,我们被强迫去思考的是如何变换数据。”

作者辩论说,按照代码序列来思考程序执行的思考方式是命令式编程语言固有的特征。文章中给出的第一个“命令式”的例子是一个简单的Java循环:

1  int sum(int[] list) {  2   int result = 0;  3   for (int i : list)  4     result += i;  5   return result;  6 }

问题在于,我可以用纯函数编程语言写出相同形式的这个例子。当然,这代码跟Haskell语言代码不是很相似,但你要知道,Haskell并不是唯一的纯函数编程语言。例如,下面的这段代码:

1 int sum([int] list):  2     result = 0  3     for i in list:  4         result = result + i  5     return result

这是一个最严格意义上的纯函数(针对相同的输入永远都产生相同的输出,没有边际效应,而且具有亲系透彻性(referentially transparent)的。)这个函数是纯函数,这是因为复合数据结构(例如list,set,map等)具有值语义(value semantics),它们的行为跟基本数据结构(例如int)一样,而不是类似Java里的那种对数据的引用。

函数式风格

我认为作者在文章里把函数式语言和函数式风格(以函数为主要表达形式和计算方式)混淆了。没错,函数式风格更倾向于使用递归而不是循环。但这并不阻碍着函数式语言里使用循环结构。

关键还在于,很多命令式语言里支持函数式编程风格。换句话说,它不是函数式编程语言的专利(尽管它们更适合)。我们应该清楚的区分这两个概念,从而避免对函数式编程语言和命令式编程语言之间的不同产生混淆。

问题是有些人并不喜欢函数式风格。例如,我更喜欢使用循环(比如上面的sum()例子里),因为这样更加清晰,好理解。但是,对于有些东西(例如遍历一个列表),我认为用递归更好。这是我的风格。。问题是,人们通常会认为,那些具有命令式编程习惯的人应该完全的转换成函数式编程语言风格。但事实上不需要这样。一些主流的函数式编程语言故意给命令式编程制造障碍。如果事情能变的简单点,人们会慢慢的转变他们的编程习惯,而不需要形式上的强迫…

你对此有想法吗?

[本文英文原文链接:A Misconception of Functional Programming? ]

载自: 外刊IT评论 http://www.aqee.net/