scheme let

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.