在 Javascript 为什么我不能用 f(f) 替换 x => f(f)(x)?
In Javascript why can't I replace x => f(f)(x) by f(f)?
我试图在 Javascript 中实现 Y 组合器。
我设法实现了以下内容:
const y0 = gen => (f => f(f))( f => gen( x => f(f)(x) ) );
const factorial0 = y0( fact => n => n<=2 ? n : n * fact(n-1) );
console.log(factorial0(5));
// 120
效果很好。
然后我在考虑表达式x => f(f)(x)
。
我的理解是表达式 x => g(x)
等价于 g
。将任何 y
应用于 x => g(x)
的计算结果为 g(y)
,而将 y
应用于 g
的计算结果也为 g(y)
.
所以我用f(f)
替换了x => f(f)(x)
。
const y = gen => (f => f(f))( f => gen( f(f) ) );
const factorial = y( fact => n => n<=2 ? n : n * fact(n-1) );
console.log(factorial(5));
// RangeError: Maximum call stack size exceeded
但此版本因堆栈溢出而崩溃。
那么 x => f(f)(x)
和 f(f)
之间有什么区别,所以一个工作,另一个崩溃。
嗯
x => f(f)(x)
是一个接受一个参数的函数,x
。当调用该函数时,它会依次调用函数 f
,将对 f
的引用作为参数传递。函数 f
returns 另一个函数,然后调用它,将 x
作为参数传递。
在老式语法中,它是
function(x) {
return f(f)(x);
}
这与 f(f)
本身有很大不同。这只是函数 "f" 的调用,其中 "f" 作为参数传递。
所以x => f(f)(x)
和f(f)
都是表达式,但是它们代表了截然不同的语义。第一个的值是对函数的引用;表达式本身 不做任何其他事情 — 特别是,函数 f()
没有被调用。 f(f)
的值是函数 f()
returns 被调用时的值——表达式 做 做某事,即函数 f()
做的任何事情.
我认为这两个表达式并不完全相同。
一方面 x => f(f)(x)
- 这会创建一个新的函数文字(因此它不会立即被调用 - 它仅在调用此函数时被调用)
另一方面 f(f)
- Javascript 中的 this 是一个调用 f
函数的表达式。所以在你的情况下会导致堆栈溢出。
我试图在 Javascript 中实现 Y 组合器。
我设法实现了以下内容:
const y0 = gen => (f => f(f))( f => gen( x => f(f)(x) ) );
const factorial0 = y0( fact => n => n<=2 ? n : n * fact(n-1) );
console.log(factorial0(5));
// 120
效果很好。
然后我在考虑表达式x => f(f)(x)
。
我的理解是表达式 x => g(x)
等价于 g
。将任何 y
应用于 x => g(x)
的计算结果为 g(y)
,而将 y
应用于 g
的计算结果也为 g(y)
.
所以我用f(f)
替换了x => f(f)(x)
。
const y = gen => (f => f(f))( f => gen( f(f) ) );
const factorial = y( fact => n => n<=2 ? n : n * fact(n-1) );
console.log(factorial(5));
// RangeError: Maximum call stack size exceeded
但此版本因堆栈溢出而崩溃。
那么 x => f(f)(x)
和 f(f)
之间有什么区别,所以一个工作,另一个崩溃。
嗯
x => f(f)(x)
是一个接受一个参数的函数,x
。当调用该函数时,它会依次调用函数 f
,将对 f
的引用作为参数传递。函数 f
returns 另一个函数,然后调用它,将 x
作为参数传递。
在老式语法中,它是
function(x) {
return f(f)(x);
}
这与 f(f)
本身有很大不同。这只是函数 "f" 的调用,其中 "f" 作为参数传递。
所以x => f(f)(x)
和f(f)
都是表达式,但是它们代表了截然不同的语义。第一个的值是对函数的引用;表达式本身 不做任何其他事情 — 特别是,函数 f()
没有被调用。 f(f)
的值是函数 f()
returns 被调用时的值——表达式 做 做某事,即函数 f()
做的任何事情.
我认为这两个表达式并不完全相同。
一方面 x => f(f)(x)
- 这会创建一个新的函数文字(因此它不会立即被调用 - 它仅在调用此函数时被调用)
另一方面 f(f)
- Javascript 中的 this 是一个调用 f
函数的表达式。所以在你的情况下会导致堆栈溢出。