Scheme 被let和let*in方案之间的差异弄糊涂了
有人能简单地解释一下这种区别吗?我不认为我从我参考过的教科书/网站中理解了这个概念。如果使用Scheme 被let和let*in方案之间的差异弄糊涂了,scheme,let,Scheme,Let,有人能简单地解释一下这种区别吗?我不认为我从我参考过的教科书/网站中理解了这个概念。如果使用let,就不能引用同一let表达式中出现的其他绑定 例如,这将不起作用: (let ((x 10) (y (+ x 6))) ; error! unbound identifier: x y) 但是如果使用let*,则可以引用出现在同一let*表达式中的以前的绑定: (let* ((x 10) (y (+ x 6))) ; works fine y) => 16
let
,就不能引用同一let
表达式中出现的其他绑定
例如,这将不起作用:
(let ((x 10)
(y (+ x 6))) ; error! unbound identifier: x
y)
但是如果使用let*
,则可以引用出现在同一let*
表达式中的以前的绑定:
(let* ((x 10)
(y (+ x 6))) ; works fine
y)
=> 16
这些都在文档中。
让
是并行的,(有点像;见下文)让*
是顺序的让
翻译为
((lambda(a b c) ... body ...)
a-value
b-value
c-value)
但是让*
作为
((lambda(a)
((lambda(b)
((lambda(c) ... body ...)
c-value))
b-value))
a-value)
并因此创建嵌套的作用域块,b-value
表达式可以引用a
,c-value
表达式可以引用b
和a
<代码>a值属于外部范围。这也相当于
(let ((a a-value))
(let ((b b-value))
(let ((c c-value))
... body ... )))
还有一个letrec
,允许递归绑定,其中所有变量和表达式都属于一个共享范围,并且可以相互引用(与初始化相关的一些注意事项)。这相当于
(let ((a *undefined*) (b *undefined*) (c *undefined*))
(set! a a-value)
(set! b b-value)
(set! c c-value)
... body ... )
(,也可作为方案中的letrec*提供,自),或
()
更新:
let
实际上并没有并行计算其值表达式,只是它们都是在出现let
表单的相同初始环境中计算的。从基于lambda
的转换中也可以清楚地看到这一点:首先在相同的外部环境中对每个值表达式进行求值,并收集结果值,然后只为每个id创建,然后为每个id创建新位置,并将每个值放在其位置。如果其中一个值表达式改变了由后续表达式访问的存储(即数据,如列表或结构),我们仍然可以看到顺序性。可能重复的@DavidPfeffer-似乎不是重复的。这个人问的是嵌套的let
s和let*
s的一个非常具体的交互,而这个人问的是一个总体概述。只是混淆了机器执行的人类解释:oI在文档中看不清楚(您的链接点在哪里,当前的版本5.3.6),所以我也很困惑。let
的文档说明“第一个表单从左到右计算val exprs
,”,因此不清楚它们是否是并行计算的。@Alexey它不会并行计算它们。正如文档中所说,“第一个表单从左到右计算val exprs
,为每个id
创建一个新位置,并将值放入位置”——这意味着首先计算值并收集结果值,只有这样,才会为每个id
创建新的位置,并将每个值放入其位置。如果val exprs
中的一个对后续存储访问的存储(即数据,如列表或结构)进行了变异,则仍然可以看到顺序性。
(let ((a *undefined*) (b *undefined*) (c *undefined*))
(let ((_x_ a-value) (_y_ b-value) (_z_ c-value)) ; unique identifiers
(set! a _x_)
(set! b _y_)
(set! c _z_)
... body ... ))