What let* expands to
It:
(let* ([a 1] [b (* 2 a)]) (cons ab))
expands to this:
((lambda (a) ((lambda (b) (cons ab)) (* 2 a))) 1)
Here is a good way to think about what lambda means in the Scheme (good, because it is both simple and accurate): it is both a label for a place in the program and an area for related variables. In Scheme, a label for a place in a program (for example, that you can goto in other languages or branches for a machine language) always has an area for related variables. You can "settle" in the program by adding values to bind to variables bound within your area.
The let schema is a way of saying: "I want to create an area in which these variables are bound, but I don't want to wait until I say their values later. I want to specify their values right here." So let is just a macro that makes a lambda and then provides values right there.
If you want the values of one of the variables to be an expression that uses another variable, for example, as b is expressed in terms of a above, then b must be defined within the scope of a . Therefore, the let* macro, which defines each next variable in the scope that includes the previous variable. Since we have a bunch of nested areas, they are implemented by a bunch of nested lambda.
Macro
Here's how to talk about how to rewrite let* as a collection of lambdas nested applications and functions:
(define-syntax let* (syntax-rules () [(__ () body ...) (begin body ...)] [(__ ([ve] [v* e*] ...) body ...) ((lambda (v) (let* ([v* e*] ...) body ...)) e)])) (let* ([a 1] [b (* 2 a)]) (cons ab)) => (1 . 2)
In Chez Scheme, you can play with this in REPL by typing (expand '(let* ([a 1] [b (* 2 a)]) (cons ab)) and seeing what happens. This is what happens when I try :
(let ([
Ben kovitz
source share