Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/350.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么用lambda修复堆栈包装函数会溢出?_Python_Lambda_Functional Programming_Stack Overflow_Y Combinator - Fatal编程技术网

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

Python 为什么用lambda修复堆栈包装函数会溢出?,python,lambda,functional-programming,stack-overflow,y-combinator,Python,Lambda,Functional Programming,Stack Overflow,Y Combinator,如果表达式的计算结果是一个参数的函数,我会认为lambda x:(表达式)(x)与表达式相同,但事实并非如此。考虑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) ret

如果表达式的计算结果是一个参数的函数,我会认为lambda x:(表达式)(x)与表达式相同,但事实并非如此。考虑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:(表达式)(x)
表达式
不同

它是一个调用时将返回
expression
结果的函数,与立即返回结果的
expression
不同

结果如何?它是一个参数的函数。但现在还没有。它需要构造、计算。这就是
expression
所做的。它计算表示“下一个”递归调用的递归函数,该递归调用可能需要由Ycombinator构造的递归函数完成

Y1
试图过早、过早、急切地找到
right
的值——它在返回计算出的递归函数之前尝试这样做。因此永远不会返回,因为
Y1
总是在返回前一个递归函数之前尝试计算下一个递归函数,以便调用它

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


不像
Y1
所尝试的那样提前了很多。

函数通过使用参数对表达式进行泛化来从表达式中提取。只有在提供参数时才对此类表达式求值,也就是说,它是惰性求值的。添加一个冗余lambda函数正是这种效果。这种技术被称为,并在经过严格评估的语言中使用,以引入懒散。