嵌套let和lambda在Scheme中的排序
Scheme 中的两个函数之间有什么区别,一个是这样定义的,
(define doSomething
(lambda (x)
(let (f (100))
(f x))))
另一个是这样定义的?
(define doSomething
(let (f (100))
(lambda (x)
(f x))))
换句话说,如果 lambda
位于 let
或者之后?
What is the difference between two functions in Scheme, one defined like this—
(define doSomething
(lambda (x)
(let (f (100))
(f x))))
and the other like this?—
(define doSomething
(let (f (100))
(lambda (x)
(f x))))
In other words, what does it matter if the lambda
is before the let
or after it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
你的代码不会运行。 :-)
我会假设你的意思是这些:
并且
在这两种情况下,你都会返回传入的参数加上 100。
然而,主要的区别(忽略关于
let
的技术细节只是lambda
的语法糖)是在第二个版本中,f
是一个自由变量。假设我们这样做:这会返回一个包含两个 lambda 的列表:第一个与之前的一样,第二个允许您更改
f
的值。两个 lambda 访问相同的f
,因此运行 setter将影响稍后对第一个 lambda 的调用。Your code won't run. :-)
I will presume that you mean these instead:
and
In both cases, you'll get back the passed-in argument plus 100.
However, the main difference (ignoring technicalities about how
let
is just syntactic sugar overlambda
) is that in the second version,f
is a free variable. Say we do this:This returns a list with two lambdas: the first of which is just like the ones previously, and the second one which allows you to change the value of
f
. Both lambdas access the samef
, so running the setter will affect later calls to the first lambda.正如克里斯指出的那样,代码不会运行。因此,我将使用一个新示例来解释
let
overlambda
习惯用法。当您用
let
包围lambda
形式时,如下所示:lambda
主体内的代码能够访问(包括修改)< code>x,即使在let
结束并返回新函数之后也是如此。这是创建“闭包”的一个示例,一开始很难理解。本质上,这意味着您可以创建具有某种“内部状态”的函数。您可以使用它来做一些事情,例如制作“累加器生成器”或制作计算它们被调用次数的函数,甚至模拟“对象”(内部状态+方法)。下面是一些人为的示例:
一个
double
函数,用于计算它被调用的次数:这个示例确实是 Paul Graham 提供的 (http://www.paulgraham.com/accgen.html)
每次<使用
1
调用 code>acc 时,它返回的值不同。有关“对象”的示例,请搜索“对象和闭包”或阅读 SICP 的相关部分:http://mitpress.mit.edu/sicp/full-text/book/book-ZH-20.html#%_sec_3.1
As Chris points out, the code isn't going to run. So I'm going to use a new example to explain the
let
overlambda
idiom.When you surround a
lambda
form with alet
like this:The code inside the body of the
lambda
is able to access (including modify)x
, even after thelet
ends and returns the new function. This is one example of creating a "closure" which is tricky to understand at first.Essentially this means that you can create a function with a kind of "internal state". You can use this to do things like make "accumulator generators" or make functions that count the number of times they've been called, or even simulate "objects" (internal state + methods). Here's some contrived examples:
A
double
function that counts the number of times it's been called:This example is really courtesy Paul Graham (http://www.paulgraham.com/accgen.html)
Each time
acc
is called with1
the value it returns is different.For examples of "objects" search for "objects and closures" or just read the relevant sections of SICP: http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-20.html#%_sec_3.1
另外两张(优秀的)海报围绕但没有明确提及的一点是:在没有
set!
的情况下,两者之间没有区别,因此可能没有理由使用您的第二种形式。One point that the other two (excellent) posters circle around but don't explicitly mention is this: in the absence of
set!
, there's no difference between the two, and therefore probably no reason to use your second form.