【问题标题】:Does the substitution model work for closures? Or do you need an environment model?替代模型是否适用于闭包?或者你需要一个环境模型?
【发布时间】:2017-10-22 16:18:22
【问题描述】:

例如。假设这是我们的 JavaScript 代码:

let a = x => {
  let y = x * 2
  return z => x + y + z
}
let b = a(1)
let c = b(2)

我可以使用替代模型对此进行评估,还是需要环境模型?

我是这样开始的:

let c = ((x => {
  let y = x * 2
  return z => x + y + z
})(1))(2)

但是我需要先评估内部表达式(用1 调用),然后才能评估外部表达式(用2 调用)。但是对于替代,它总是由外而内。

这是否表明替代模型在这里不合适?还是从内向外和从外向内评估是否符合犹太教规?还是有其他的方式来看待它?

【问题讨论】:

  • 如果您的代码不改变绑定的范围变量,则不需要环境模型。
  • 在纯函数中,计算的顺序无关紧要。但即使是由外而内,您也必须先将应用程序操作的左侧评估为函数,然后才能应用它。

标签: javascript functional-programming computer-science lambda-calculus


【解决方案1】:

替换模型适用于闭包。基本上,您将绑定替换为其绑定值。您不需要环境模型。

const b = a(1)                  // ==
const b = z => 1 + (1 * 2) + z

const c = b(2)             // ==
const c = 1 + (1 * 2) + 2  // ==
const c = 5              

只有当你真的需要使用let(如果你真的重新绑定它)你需要一个环境模型时。

当涉及到评估顺序时,很明显,在像a(1)(2) 这样的两个调用中,您不能首先使用参数2 进行第二次调用,因为它是根据a(1) 的结果调用的。因此,您需要知道a(1) 的结果,因此您需要先替换它,然后对该结果进行下一次调用。

let c = (x => {
  let y = x * 2
  return z => x + y + z
})(1)(2)
// substituting 1 for x ==>
let c = (z => 1 + 2 + z)(2)
// substituting 2 for z ==>
let c = 1 + 2 + 2

【讨论】:

  • 我明白了。那么替换的操作顺序是什么?是否认为由内而外或由外而内评估无关紧要,因为无论哪种方式,您都会得到相同的结果?
  • @bcherny 我已添加到答案中。
  • 我希望第二行是let c = (let y = 1*2 in z => x + 1 + z)(2)
  • @Bergi 最好只替换它,因为该表达式在您编写它的方式上不是有效的 JS,并且由于卷曲消失了,范围不再明显。
猜你喜欢
  • 1970-01-01
  • 2013-12-04
  • 1970-01-01
  • 2012-07-12
  • 1970-01-01
  • 1970-01-01
  • 2019-01-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多