谁能向我解释一下 Scheme 中的这个表达式将如何返回 100?
(((lambda (f) ((lambda (g) (lambda (h) (f (g (h 4))))) double)) square) inc)
我知道它以某种方式分解为"(2*(4+1))^2",但对于我的生活,我不知道如何。
这是针对有类似问题的考试。其中大约有 6 或 7 个,我们必须在大约 1 或 2 分钟内找到它们的答案(因为它们只是测试的 1 个部分)。我们的教授除了努力学习之外没有提供任何帮助,但我完全不知道如何做到这一点,更不用说快速了。
任何帮助将不胜感激!谢谢。
让我们一步一步地走 - 注意一个好的缩进如何使一切更容易理解!
(((lambda (f) ; call outermost lambda, f is bound to square
((lambda (g) ; call mid lambda, g is bound to double
(lambda (h) ; return lambda, h is unbound
(f (g (h 4)))))
double))
square)
inc)
上面的表达式已经简化为:
((lambda (h)
(square (double (h 4))))
inc)
现在我们最后调用最后一个lambda
,h
绑定到inc
,得到如下表达式:
(square (double (inc 4)))
=> 100
查看表达式,您马上看到其中大部分是运算符。调用的形式为:
(operator operands ...)
因此,您知道运算符是这样的:
((lambda (f)
((lambda (g)
(lambda (h)
(f (g (h 4)))))
double))
square)
唯一的操作数是这样的:
inc
查看运算符时,您再次看到左括号,这意味着它也是一个调用。新运算符将f
绑定到square
,并执行新的调用绑定g
double
并且由于最后一个lambda
周围没有括号,因此返回是预期的函数/闭包/过程。因此,我们可以在不更改其含义的情况下替换绑定,在这种情况下,您可以得到:
(lambda (h)
(square (double (h 4))))
现在让我们再次执行顶部(operator operand)
:
((lambda (h)
(square (double (h 4))))
inc)
在这里你看到h
绑定到inc
.如果我们用程序主体替换它,我们可以替换整个事情:
(square (double (inc 4))) ; ==> 100
当您看到((lambda ...) ...)
时,您正在查看立即调用的匿名过程。它与(something ...)
相同,后者也是一个调用,但在这里变量something
应该被计算为一个过程。(((lambda ..
或((something ...
这两个方面多加括号应该告诉您该函数应返回随后调用的函数。这是标准正确的方案,但不是最常见的,所以只要学会意识到这些,因为它需要更多的几秒钟的注意力。在自己编写代码时,请考虑使用绑定明确这一点:
(let ((helper (something a b c))))
(helper d))
而不是:
((something a b c) d)
尽管这些在撰写本文时看起来同样简单,但当您长时间停顿后再次查看时,您也会感谢自己。