let
let
binds in parallel because
(let ((+ *) (* +))
(+ 3 (* 4 5)))
actually expands to
((lambda (+ *)
(+ 3 (* 4 5)))
* +)
so Scheme does its usual thing:
- the parameters
*
and+
are evaluated to their respective values (the procedures*
and+
) in some sequence - then bound to the formal parameters
+
and*
(this also happens in some sequence, but it doesn't matter which in both cases) - then the body of the inner function is evaluated as
(* 3 (+ 4 5))
.
Just add a printf
to confirm:
(let ((+ *) (* +))
(printf "+ is ~a and * is ~a \n" + *)
(+ 3 (* 4 5)))
=>
+ is #<procedure:*> and * is #<procedure:+>
27
let*
If you expect the binding to happen in sequence, then you have to use let* since
(let* ((+ *) (* +))
(+ 3 (* 4 5)))
expands to
((lambda (+)
((lambda (*)
(+ 3 (* 4 5)))
+))
*)
so
*
is bound to+
- then
+
which has already be bound to*
, is bound to*
again so this actually has no effect - then the expression becomes
(* 3 (* 4 5))
and since the second binding has no effect this is equivalent to simply
(let ((+ *))
(+ 3 (* 4 5)))