Lambda微积分 - 使用Mocking Bird表示的函数似乎应该是递归的但不是

时间:2017-11-02 19:06:32

标签: javascript python recursion functional-programming lambda-calculus

使用JavaScript。让我们定义以下内容:

M = f => f(f)  // Mocking Bird
I = a => a  // Identity

假设现在我们写这个表达式

M( f => M( x => f) ) 

这似乎是递归的并且达到了最大的callstack。让我们展开一次

( f => M( x => f) )  (f => M( x => f) )

我们看到我们可以继续前进

(f => (x => f)( x => f))(f => (x => f)( x => f))

(x => (f => (x => f)( x => f)))(x => (f => (x => f)( x => f)))

......等等。但是在浏览器或节点中,这不是递归的。它的行为类似于Identity

I('foobar')
// returns 'foobar'

M( f => M( x => f) )('foobar')
// returns 'foobar'

(x => (f => (x => f)( x => f)))(x => (f => (x => f)( x => f))) ('foobar')
// returns 'foobar'

请解释为什么函数在达到最大调用堆栈之前不会自行调用,而是返回一个行为类似于Identity的函数

使用Python

可以表达同样的现象
M = lambda f: f(f)
I = lambda a: a

M( lambda f: M(lambda x: f)) ('foobar')
# returns 'foobar'

I('foobar')
# returns 'foobar'

更新

开始
M( f => M( x => f) ) 

如果我们写出内部M( x => f)

M( f => ( x=> f )(x => f) )

我们发现传递给(x => f)(x => f)的内容并不重要,x会被忽略,只返回f

M( f => f ) 

这只是

f => f

1 个答案:

答案 0 :(得分:1)

 M(/*a*/ f => M( /*b*/ x => f) )('foobar')
使用 f = a

调用

a

M(/*b*/ x => *a*) 
调用

b ,x为b,返回:

/*a*/ f => M(/*b*/ x => f)

用“foobar”调用,所以f是“foobar”:

M(/*b*/ x => "foobar")

“foobar”被退回

基本上它起作用是因为:

M( x => f)

始终返回 f ,因此整个事情等于

M( f => f )

然后呢:

(f => f)(f => f)

f => f