我们先看下面这个J(一种应用语言)程序的例子: +/ % # 这个程序计算来自标准输入的一列数字的平均值。结果(因为没有给结果指定参数名)使用标准输出显示。 这个J 平均值程序有几个有趣的特点.
使用J 平均值程序时,你应该把程序和数字表放在一个J计算机(解释器)的标准输入流中。 [jhowland@Ariel jhowland]$ echo "(+/ % #) 1 2 3" | jconsole (+/ % #) 1 2 3 2 [jhowland@Ariel jhowland]$ 这个J 平均值程序包含三个功能。
当一个三功能的程序被应用到一个单一的参数 ,y,则下列组成的交叉规则被使用。 (f g h) y = (f y) g (h y) 在这个J 平均值程序中, f是功能+ / ,表示相加;g是功能% ,表示相除;#是计数功能,计算元素列表中的元素的个数。 J求平均值的程序需要更多解释。/ (insert)是一个函数,它的作用是使两个参数的函数(二价元素)可用,它的返回值是一个重复获取导出函数参数列表中参数的函数,。例如,+/调用一个函数计算它的参数列表中的参数之和。*/导出一个函数计算它的参数列表中的参数。许多函数式语言允许在导出函数中设定返回值为函数类型。然而多数命令式语言却没有这个功能。 例如,调用导出函数 +/可以计算它的参数列表之和,*/计算参数列表之积。 2.3 表达式函数式语言专门处理产值表达式。通常情况下,一个表达式产生一个值。 命令式语言使用语言结构(如赋值)——在计算过程中,被用来去描述指定内存单元的状态变化,如 C 中的 while 循环。这样的语言中包含很多不产生任何值的语句,以及一些对其他条目产生副作用的语句,如修改其他条目的值。 2.4 副作用命令式语言可能会有产生副作用的语句。如,在C语言写的平均值程序中包含count++;这样一条语句,该语句引用了count的值(这个平均值程序并没有用到这个引用),并将它的值增1。这个C语言版的程序依赖于这个副作用。 纯函数式的语言没有副作用。 3 为什么要学习函数式编程函数式编程之所以重要有以下原因: 3.1 可任意赋值函数式语言允许程序不事先分配内存。结构化的命令式语言(没有goto语句)使得程序容易派生,便于理解和追踪。类似的,assignment-free函数语言也有相同的优点。 3.2 抽象层次高函数式语言提倡使用更高层次的抽象。例如,函数可以作为函数调用的返回值。函数可以像数据一样被操纵。现存的函数可以被修改,也可以联合组成新的函数。函数式编程包含大量的工作单元而很少使用个体声明。算法可以被直接实现而不引用任何数据。 3.3 并行计算函数式编程语言允许应用程序处理数据集合而不是强制性迭代处理集合中的每项数据。这些应用程序可以任意赋值并且独立求值,函数式编程语言提供了并行处理结构化数据的理想范式。 3.4 人工智能函数式语言在人工智能领域得到广泛的应用。AI研究者在 LISP程序语言的基础上做了许多早期的开发工作,虽然它不是一个纯粹的函数式语言,但对大多数函数式语言的设计产生了重要的影响。 3.5 原型设计 在复杂系统的设计,函数式语言通常会制定设计规范并且开发一个原型实现系统的主要功能。函数式语言简单的语义和严格的数学基础使它成为复杂系统功能设计的理想工具。 3.6 理论函数式语言的数学基础提供了与计算机科学理论的衔接。问题的可判定性可能代表了不同函数框架应用。例如,denotational语义的本质是将命令式程语言序转化为等价的函数式语言程序。 4 J函数式编程语言J编程语言[Burk 2001,Bur 2001,Hui 2001]是一个函数式编程语言。J使用插入记号和特殊符号表示原函数,诸如+或者 %,或者在 .或者 :后面添加特殊符号或者单词。每个函数名称可能作为一元参数(一个变元,通常写在右边)或者二元参数(两个变元,一个在左边,另一个在右边)。 J语言内置函数列表在数字1和2里展示。这些数字展示了在*左边的一元函数定义和在右边的二元函数定义。例如,函数标记+:代表一元doubl参数e和二元not-or(nor)参数。 Figure 1: J Vocabulary, Part 1 J使用简单的规则判定函数表达式的优先级。一元变量或者右边的二元变量是整个表达式右边的值。左边二元变量的值作为优先项赋值给左边的二元变量。括号用于更改表达式的优先级。例如,表达式3*4+5值为27,然而表达式(3*4)+5的值为17。 Figure 2: J Vocabulary, Part 2 高优先级函数(返回值为函数的函数)必须在其它函数调用前完成(必须)。有两种类型的高优先级函数同 ; adverbs (高优先级一元函数)和conjunctions (高优先级二元函数)。数字1和 2用粗斜体表示adverbs,用粗体表示conjunctions 。例如,与运算符 (Curry)绑定一个固定参数值的二元函数,返回一个一元函数(4&*导出一个求4的幂级数的一元函数).。 |