繁体   English   中英

为什么用lambda修复堆栈包装函数会溢出?

[英]Why does wrapping a function with a lambda fix stack overflow?

如果expression求值是一个参数的函数,我会认为lambda x:( expression )(x)与expression相同-但实际上并非如此。 考虑Y组合器的以下两个定义:

def Y1(F):
    left = lambda x: x(x)
    right = lambda x: F(x(x))
    return left(right)

def Y2(F):
    left = lambda x: x(x)
    right = lambda x: lambda y: (F(x(x)))(y)
    return left(right)

Y2实际上按预期工作,但是调用Y1会引起堆栈溢出。 为什么在行为上有这种差异?

不, lambda x: (expression)(x)expression并不相同。

它是一个函数,在调用时返回expression的结果,而不同于立即返回其结果的expression

那是什么结果? 它是一个参数的函数。 但这还不存在。 它需要构造,计算。 这就是expression作用。 它计算表示“下一个”递归调用的递归函数,该递归函数可能需要Y组合器构造的递归函数来完成

Y1试图过早,过分急切地找到right的值-它试图返回计算的递归函数之前执行此操作。 因此,它永远不会返回,因为Y1总是在返回前一个递归函数之前尝试计算下一个递归函数,以便可以对其进行调用。

Y2构建递归函数, 计算时,将需要下一个递归函数; 但还不是“现在”。 它将其构造为lambda函数,这会延迟实际计算。 lambda函数的构建是一个简单的一步过程,该过程很快完成,然后返回计算出的递归函数,因此可以使用它,并且仅当/何时它将确定下一级别的递归调用需要在执行该操作时,它将在该时间点调用该lambda, 以在该时间 即在调用它之前构造下一个递归函数。

不是这样的方式提前为Y1正在试图做的事。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM