谁能简单解释一下区别?我不认为我从我咨询过的教科书/网站中理解了这个概念。
			
			10929 次
		
2 回答
            30        
        
		
Let是并行的,(有点;见下文) let*是顺序的。Let翻译为
((lambda(a b c)  ... body ...)
  a-value
  b-value
  c-value)
但let*作为
((lambda(a)
    ((lambda(b)
       ((lambda(c) ... body ...)
        c-value))
     b-value))
  a-value)
并因此创建嵌套范围块,其中b-value表达式可以引用a,c-value表达式可以同时引用b和a。a-value属于外部范围。这也相当于
(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 ... )
(在 Racket 中,也可以letrec*在 Scheme 中使用,从R6RS 开始),或者
(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 ... ))
(在方案中)。
update:let实际上并没有并行地评估它的值表达式,只是它们都在let表单出现的相同初始环境中被评估。这从基于 - 的翻译中也很清楚:首先在相同的外部环境lambda中评估每个值表达式,并收集结果值,然后才为每个id创建新位置,并将值放入每个位置. 如果其中一个值表达式改变了由后续存储访问的存储(即数据,如列表或结构),我们仍然可以看到顺序性。
于 2013-02-21T15:28:56.837   回答
    
    
            29        
        
		
如果使用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
这一切都在文档中。
于 2013-02-21T13:33:56.750   回答