Confundido por la diferencia entre let y let* en el Esquema
¿Puede alguien explicar la diferencia simplemente? No creo entender el concepto de los libros de texto / sitios que he consultado.
2 answers
Si usa let
, no puede hacer referencia a enlaces definidos previamente en la misma expresión let
. Por ejemplo, esto no funcionará:
(let ((x 10)
(y (+ x 6))) ; error! unbound identifier in module in: x
y)
Pero si usas let*
, es posible referirse a enlaces anteriores en la misma expresión let*
:
(let* ((x 10)
(y (+ x 6))) ; works fine
y)
=> 16
Está todo aquí en la documentación.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-02-21 13:33:56
Let
es en paralelo, (tipo de; ver más abajo)let*
es secuencial. Let
se traduce como
((lambda(a b c) ... body ...)
a-value
b-value
c-value)
Pero let*
as
((lambda(a)
((lambda(b)
((lambda(c) ... body ...)
c-value))
b-value))
a-value)
Y está creando así bloques de ámbito 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
. a-value
pertenece al ámbito externo. Esto también equivale a
(let ((a a-value))
(let ((b b-value))
(let ((c c-value))
... body ... )))
También Hay letrec
, permitiendo recursiva enlaces, donde todas las variables y expresiones pertenecen a un ámbito compartido y pueden referirse entre sí (con algunas advertencias relativas a 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 raqueta, también disponible como letrec*
en Scheme, desde R6RS), o hasta
(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 Scheme ).
Actualización: let
en realidad no evalúa 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 se desprende claramente de la traducción basada en lambda
: primero se evalúan las expresiones de valor cada una en el mismo entorno externo, y se recopilan los valores resultantes, y solo entonces se crean nuevas ubicaciones para cada id y los valores se colocan cada uno en su ubicación. Todavía podemos ver la secuencialidad si una de las expresiones de valor muta un almacenamiento (es decir, datos, como una lista o una estructura) al que una.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-06 10:19:30