LET
LET*
Both LET
and LET*
define local variables and evaluate forms contained in the LET/LET* context, where the local variables are bound. They accept any number of arguments, but first must be list of the symbols representing local variables, or initializer lists. Remaining arguments will be evaled as in PROGN
.
(let (a b c) ... )
First example just defined A, B and C as local variables, bound to NIL. In the following example, we use initializer lists:
>(let ((a 1) (b 2)) ; local variables A, B (print (+ a b)) ; forms are evaled sequentially (setq a 5) ; SETQ assigns value to the local A (print (+ a b)) T) ; last form is returned 3 ; side effect of PRINT prints 7 ; side effect of PRINT prints T ; result of the LET form
It is possible to locally shadow global variables with LET
, apart from those defined as constants. In LabLISP, PI
is not defined as constant, so we can do this:
>(defun circ (r) (* 2 pi r)) ; define function calculating circumference CIRC USER>(circ 1) 6.28318 USER>(let ((pi 3.1)) (circ 1)) ; local value shadows the global variable 6.2
The difference between LET
and LET*
is in the way they evaluate the initializing forms. In LET
, all the forms are evaluated first and then bound to the symbols. On the other hand, in LET*
, the forms are evaluated sequentially, and the previously initialized symbols are already bound in the context. So one can use previous local variable in the initialization of the next:
>(let* ((a 3) (b (* 2 a))) (+ a b)) ; B is initialized as 2*3 9