scheme - map racket
Confundido por la diferencia entre let y let*en Scheme (2)
¿Alguien puede explicar la diferencia simplemente? No creo que entienda el concepto de los libros de texto / sitios que he consultado.
Si usa let
, no puede hacer referencia a enlaces previamente definidos en la misma expresión de let
. Por ejemplo, esto no funcionará:
(let ((x 10)
(y (+ x 6))) ; error! unbound identifier in module in: x
y)
Pero si usa let*
, es posible referirse a enlaces anteriores en la misma expresión let*
:
(let* ((x 10)
(y (+ x 6))) ; works fine
y)
=> 16
Todo está here en la documentación.
Let
es paralelo, (tipo de; ver más abajo) let*
es secuencial. Let
traduce como
((lambda(a b c) ... body ...)
a-value
b-value
c-value)
pero let*
como
((lambda(a)
((lambda(b)
((lambda(c) ... body ...)
c-value))
b-value))
a-value)
y, por lo tanto, está creando bloques de alcance anidados donde la expresión b-value
puede referirse a a
, y la expresión c-value
puede referirse tanto a b
como a
. a-value
pertenece al ámbito externo. Esto también es equivalente a
(let ((a a-value))
(let ((b b-value))
(let ((c c-value))
... body ... )))
También hay letrec
, que permite enlaces recursivos, donde todas las variables y expresiones pertenecen a un ámbito compartido y pueden referirse entre sí (con algunas advertencias relacionadas con la inicialización). Es equivalente a
(let ((a *undefined*) (b *undefined*) (c *undefined*))
(set! a a-value)
(set! b b-value)
(set! c c-value)
... body ... )
( en Racket , también disponible como letrec*
en Scheme, desde R6RS ), o para
(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 ... ))
( en esquema ).
actualización: let
no evalúa realmente sus expresiones de valor en paralelo, es solo que todas se evalúan en el mismo entorno inicial donde aparece el formulario let
. Esto también queda claro en la traducción basada en lambda
: primero, las expresiones de valor se evalúan cada una en el mismo entorno externo , y los valores resultantes se recopilan, y solo entonces se crean nuevas ubicaciones para cada ID y los valores se ponen cada uno en su ubicación. Todavía podemos ver la secuencia si una de las expresiones de valor muta un almacenamiento (es decir, datos, como una lista o una estructura) a los que accede uno posterior.