我不同意WReach的回答。让我们对他的回答进行一些解构,看看分歧来自何处。
首先,他的代码:
function allOdd(words) {
var result = true;
for (var i = 0; i < length(words); ++i) {
var len = length(words[i]);
if (!odd(len)) {
result = false;
break;
}
}
return result;
}
和
function allOdd(words) {
return apply(and, map(compose(odd, length), words));
}
要注意的第一件事是他正在混合:
编程,并且缺少迭代样式编程比典型功能样式具有更明确的控制流的功能。
让我们快速谈谈这些。
以表达为中心的样式是事物尽可能多地评估事物的一种方式。尽管函数式语言因对表达式的热爱而闻名,但实际上可能会有一种没有可组合表达式的函数式语言。我要弥补一个问题,没有表达式,只有语句。
lengths: map words length
each_odd: map lengths odd
all_odd: reduce each_odd and
这与以前给出的几乎相同,除了函数完全通过语句和绑定链进行链接。
以迭代器为中心的编程风格可能是Python采取的一种。让我们使用纯迭代的,以迭代器为中心的样式:
def all_odd(words):
lengths = (len(word) for word in words)
each_odd = (odd(length) for length in lengths)
return all(each_odd)
这是不起作用的,因为每个子句都是一个迭代过程,并且它们通过堆栈帧的显式暂停和恢复而绑定在一起。语法可能会部分地从功能语言中获得启发,但会应用于其完全迭代的实施方式。
当然,您可以压缩以下内容:
def all_odd(words):
return all(odd(len(word)) for word in words)
命令性现在看起来还不错,是吗?:)
最后一点是关于更明确的控制流程。让我们重写原始代码以使用此代码:
function allOdd(words) {
for (var i = 0; i < length(words); ++i) {
if (!odd(length(words[i]))) {
return false;
}
}
return true;
}
使用迭代器,您可以:
function allOdd(words) {
for (word : words) { if (!odd(length(word))) { return false; } }
return true;
}
那么,什么是功能性语言的点,如果偏差在:
return all(odd(len(word)) for word in words)
return apply(and, map(compose(odd, length), words))
for (word : words) { if (!odd(length(word))) { return false; } }
return true;
函数式编程语言的主要定义特征是,它消除了作为典型编程模型一部分的突变。人们通常认为这是一种功能性编程语言没有语句或不使用表达式,但这只是简化。功能语言用行为声明代替显式计算,然后对语言进行简化。
将自己限制在此功能子集中,可以使您对程序的行为有更多的保证,并且可以更自由地编写它们。
使用功能语言时,制作新功能通常与编写紧密相关的功能一样简单。
all = partial(apply, and)
如果您尚未显式控制函数的全局依赖关系,这将不简单,甚至可能无法实现。函数式编程的最大特点是,您可以一致地创建更多的通用抽象,并相信可以将它们组合成更大的整体。