;; ;; let, let* and letrec sample code. ;; The idea is to demonstrate the difference ;; between them. In a nutshell: ;; each of let, let* and letrec contain ;; declaration and initialization of some variables. ;; The difference between let, let* and letrec is ;; where the variable binding hold (and don't hold). ;; ;; a procedure that simplifies output of a line composed of ;; a sequence of things. (define show (lambda l (map display l) (display "\n"))) ;; let: the variables declared in the let are bound only to the ;; body of the let, not to any of the expressions used to ;; initialize the variables. (define x 22) (define y 50) (let ((x 3) (y (+ x 1))) (show "x = " x ", y = " y)) ;; will print x=3, y=23 ;; In other words, the expression (+ x 1) in the initialization of y uses ;; the global x defined as 22, not the let-bound x. The scope of the ;; let-bound x is restricted to the body of the let, it doesn't apply to ;; the initialization of y. ;; It is OK for scheme to evaluate the initialization code for y before it ;; has even determined what value x will get. ;; let*: the initialization values and assignment of values to variables ;; is done from left to right. So the first declared variable will be ;; and available for use in the second variable declaration/initialization. ;; note that global x and y are already defined here (above the example ;; code for let). (let* ((x 3) (y (+ x 1))) (show "x = " x ", y = " y)) ;; will print x = 3, y = 4 ;; The value of the let-bound x is computed first, and available for ;; use in the initialization expression for y. None of the global ;; variables x,y play a part in this code... ;; letrec: the initialization is done in any order, but each of the ;; let-bound variables is in the scope of all the variable initialization ;; code. This is typically used only when defining a function... (letrec ((x 3) (y (+ x 1))) (show "x = " x ", y = " y)) ;; might work, might not - it depends on the evaluation order. ;; if the assignment of x to 3 is done first, then x has a value ;; and is available for use in the code (+ x 1). If y is initialized ;; first, this code will generate an error, since the expression ;; (+ x 1) refers to x which has no value yet. ;; here is a better letrec example (letrec ((len (lambda (ls) (if (null? ls) 0 (+ 1 (len (cdr ls))))))) (len '(1 2 3)))