c := 0
for i := I step 1 until n do
c := c + a[i] * b[i]
Several properties of this program are
worth noting:
Its statements operate on an invisible "state" according to complex
rules.
It is not hierarchical. Except for the right side of the assignment
statement, it does not construct
complex entities from simpler ones.
(Larger programs, however, often do.)
It is dynamic and repetitive. One must mentally execute it to
understand it.
It computes word-at-a-time by repetition (of the assignment) and by
modification (of variable i).
Part of the data, n, is in the program; thus it lacks generality and
works only for vectors of length n.
It names its arguments; it can only be used for vectors a and b.
To become general, it requires a
procedure declaration. These involve
complex issues (e.g., call-by-name
versus call-by-value).
Its "housekeeping" operations are represented by symbols in
scattered places (in the for statement
and the subscripts in the assignment).
This makes it impossible to
consolidate housekeeping operations,
the most common of all, into single,
powerful, widely useful operators.
Thus in programming those operations
one must always start again at square
one, writing "for i := ..." and
"for j := ..." followed by
assignment statements sprinkled with
i's and j's.
8 个回复
isunt
赞同来自:
Map和Filter在OO编程中占有一席之地。列表推导和生成器函数旁边。 少减少。减少算法可以快速吸收比它应得的更多的时间;通过一点思考,手动编写的reduce循环将比reduce更有效,reduce将一个经过深思熟虑的循环函数应用于序列。 Lambda永远不会。 Lambda没用。人们可以说它实际上做了某些事情,所以它并非完全没用。第一:Lambda不是句法“糖”;它使事情变得更大,更丑陋。第二:10,000行代码中的一次认为你需要一个“匿名”函数,在20,000行代码中变成了两次,这消除了匿名的价值,使其成为维护责任。 然而。 无对象状态变化编程的功能风格本质上仍然是OO。您只需创建更多对象并减少对象更新。一旦开始使用生成器功能,许多OO编程就会向功能方向漂移。 每个状态更改似乎都转换为生成器函数,该函数从旧对象构建新状态的新对象。这是一个有趣的世界观,因为对算法的推理要简单得多。 但是没有使用reduce或lambda的调用。
eipsum
赞同来自:
这个问题似乎在这里被忽略了:
否.FP值带来的并发性在于消除计算中的状态,这最终导致并发计算中意外错误的难以掌握的肮脏。但这取决于并发编程习语本身不是有状态的,不适用于Twisted。如果有利用无状态编程的Python的并发习惯用法,我不知道它们。get
赞同来自:
内容太长未翻译
wanimi
赞同来自:
内容太长未翻译
gsint
赞同来自:
以下是关于何时/为什么要进行功能编程的正面答案的简短摘要。
sort
提供复杂的密钥时,我会使用lambda
,例如list.sort(key=lambda x: x.value.estimate())
bquos
赞同来自:
我每天都在使用Python编程,我不得不说,对于OO或功能性过多的“徘徊”可能导致缺少优雅的解决方案。我相信这两种范式对某些问题都有其优势 - 我认为当你知道使用什么方法时。在为您提供干净,可读且高效的解决方案时,请使用功能性方法。 OO也是如此。 这就是我喜欢Python的原因之一 - 事实上它是多范式的,让开发人员选择如何解决他/她的问题。
vanimi
赞同来自:
FP不仅对并发很重要;实际上,在规范的Python实现中几乎没有并发性(可能3.x会改变吗?)。在任何情况下,FP都很适合并发,因为它导致程序没有或没有(显式)状态。由于一些原因,国家很麻烦。一个是他们分配计算硬(呃)(这是并发参数),另一个,在大多数情况下更重要的是,是一种造成错误的倾向。当代软件中最大的错误来源是变量(变量和状态之间存在密切关系)。 FP可能会减少程序中变量的数量:被压扁的错误! 通过在这些版本中混合变量,您可以看到有多少错误:
与(警告,my.reduce
的参数列表不同于python的reduce
;后面给出的理由) 正如你所看到的那样,事实上FP可以减少与变量相关的错误射击自己的机会。 此外,可读性:可能需要一些培训,但functional
比imperative
更容易阅读:您看到reduce
(“好吧,它将序列减少为单个值”),mul
(“通过乘法”)。其中imperative
具有for
循环的通用形式,其中包含变量和赋值。这些for
周期看起来都一样,所以为了了解imperative
中发生了什么,您需要阅读几乎全部内容。 然后是顽固和灵活。你给我imperative
并且我告诉你我喜欢它,但是想要一些东西来总结序列。没问题,你说,然后你走了,复制粘贴: 你能做些什么来减少重复?好吧,如果运营商是价值观,你可以做类似的事情 等一下!operators
提供值为的运算符!但是...... Alex Martelli已经谴责了reduce
......看起来如果你想留在他建议的范围内,你注定要复制粘贴的管道代码。 FP版本更好吗?你当然还需要复制粘贴吗? 好吧,这只是半成品方法的神器!放弃命令式def
,您可以将两个版本合同 甚至 (func.partial
是my.reduce
的原因) 运行速度怎么样?是的,在像Python这样的语言中使用FP会产生一些开销。在这里,我只是鹦鹉几位教授对此有何评论:nodit
赞同来自:
标准函数filter(),map()和reduce()用于列表上的各种操作,并且所有这三个函数都需要两个参数:函数和列表 我们可以定义一个单独的函数并将其用作filter()等的参数,如果该函数被多次使用,或者如果函数太复杂而无法写入一行,则可能是个好主意。但是,如果它只需要一次并且它非常简单,那么使用lambda构造生成(临时)匿名函数并将其传递给filter()会更方便。 这有助于
readability and compact code.
使用这些函数,也会变成efficient
,因为列表元素的循环是在C中完成的,这比在python中循环要快一点。 除了抽象,分组等之外,在维护状态时强制需要面向对象的方式。如果要求非常简单,我会坚持使用功能而不是面向对象编程。