Functional programming 什么时候重击比较好?

Functional programming 什么时候重击比较好?,functional-programming,lazy-evaluation,thunk,Functional Programming,Lazy Evaluation,Thunk,什么时候使用懒惰的评估而不是急切的评估更好?如果您知道表达式将只计算一次,或者可能永远不会计算,这会更好吗?如果您有选择权,请对可能根本不会计算的表达式使用延迟计算,或者在计算时的某些情况下可能导致编程错误 经典案例在大多数C语言中实现,称为“短路运算符”: 这里,n/i>100仅在i不为0时计算。这很好,因为它避免了零除错误。如果您有选择权,请对可能根本不进行计算的表达式使用延迟计算,或者在某些情况下计算时可能导致编程错误 经典案例在大多数C语言中实现,称为“短路运算符”: 这里,n/i>10

什么时候使用懒惰的评估而不是急切的评估更好?如果您知道表达式将只计算一次,或者可能永远不会计算,这会更好吗?

如果您有选择权,请对可能根本不会计算的表达式使用延迟计算,或者在计算时的某些情况下可能导致编程错误

经典案例在大多数C语言中实现,称为“短路运算符”:


这里,
n/i>100
仅在
i
不为0时计算。这很好,因为它避免了零除错误。

如果您有选择权,请对可能根本不进行计算的表达式使用延迟计算,或者在某些情况下计算时可能导致编程错误

经典案例在大多数C语言中实现,称为“短路运算符”:

这里,
n/i>100
仅在
i
不为0时计算。这很好,因为它避免了零除错误。

是支持惰性评估的典型论据,主要是作为改进模块化的促进者

我可以给你们举个例子,用埃拉托斯烯筛出的惰性素数公式

primes=(cons 2.diff[3..).bigU.map(\p->[p*p,p*p+p..)primes
)是函数组合,
diff
是集合差异,
bigU
找到(有序的,递增的)数字列表的并集,
map
map
,等等……,如果没有惰性语义,它们必须混合在一起,而不是使用这些漂亮的单独模块化函数与函数组合链接在一起。

是支持惰性计算的典型论据,主要是作为改进模块化的促进者

我可以给你们举个例子,用埃拉托斯烯筛出的惰性素数公式

primes=(cons 2.diff[3..).bigU.map(\p->[p*p,p*p+p..)primes

)是函数组合,
diff
是集合差异,
bigU
找到(有序的,递增的)数字列表的并集,
map
map
,等等……,如果没有惰性语义,它们必须混合在一起,而不是使用这些漂亮的单独模块化函数与函数组合链接在一起。

一般来说,这有点难说,至少以任何有用的方式。这取决于语言和任务。@Chuck我在回答中链接了一篇著名的文章,这篇文章提出了一个一般性的论点。@WillNess:我已经读过函数式编程的重要性,只是再次浏览一遍以刷新我的记忆,我认为它并没有很好地回答这个问题。它解释了普遍的惰性评估的一些一般好处,但它没有探讨惰性评估与严格评估的实际权衡,也没有探讨如何评估在给定情况下使用哪种方法更好(例如,在Haskell中,通过切换到严格评估,可以消除整类问题)。我同意这篇文章很有启发性和相关性,但它并没有真正回答这里提出的问题。@Chuck我读这个问题是为了什么对程序员更好,而不是作为一个实现上的权衡问题。这在一般情况下是很难说的,至少在任何有用的方面是这样的。这取决于语言和任务。@Chuck我在回答中链接了一篇著名的文章,这篇文章提出了一个一般性的论点。@WillNess:我已经读过函数式编程的重要性,只是再次浏览一遍以刷新我的记忆,我认为它并没有很好地回答这个问题。它解释了普遍的惰性评估的一些一般好处,但它没有探讨惰性评估与严格评估的实际权衡,也没有探讨如何评估在给定情况下使用哪种方法更好(例如,在Haskell中,通过切换到严格评估,可以消除整类问题)。我同意这篇文章很有启发性和相关性,但它并没有真正回答这里提出的问题。@Chuck我读这个问题是为了什么对程序员更好,而不是作为一个实现的权衡问题。更基本的例子是,您不需要将if作为一个特殊语句,但可以将其作为一个标准函数来实现,如果为“then”和“else”参数传递thunk。当然,您需要一些原语来选择要计算的原语,这可以通过布尔多态性(例如SmallTalk)来解决。更基本的示例是,您不需要将if作为特殊语句,但如果您为“then”和“else”参数传递thunks,则可以将其作为标准函数实现。当然,您需要一些原语来选择要计算的原语,这可以通过布尔多态性(例如SmallTalk)来解决
if (i != 0 && n/i > 100) ...