[cl-faq] faq answer: Why are there both LET and LET*?

Larry Clapp larry at theclapp.org
Wed Jun 21 08:23:14 CDT 2006


*** Why are there both LET and LET*?

LET and LET* both calculate values and establish bindings.  They
differ in when they do it.  LET calculates all values, and then
establishes new bindings all at once, in parallel.  LET* binds each
variable to a new value one at a time, serially.

This Lisp 

  (let (a b c)	; ignore this for now
    (setq a 1)
    (setq b 2)
    (setq c 3)
    (let ((a 10)
	  (b (1+ a))
	  (c (1+ b)))
      (format t "~D ~D ~D~%" a b c)))
  prints=> 10 2 3

is similar to this C

  int a, b, c;

  a = 1;
  b = 2;
  c = 3;

  int tmp_a = 10;
  int tmp_b = a + 1;
  int tmp_c = b + 1;

  a = tmp_a;
  b = tmp_b;
  c = tmp_c;

  printf( "%d %d %d\n", a, b, c );

In the LET, the calculation of B cannot be affected by the new value
of A, because that new value has not been established yet.  Similarly
for C not being affected by the new value of B.  So we say that LET
binds variables "in parallel".

LET* doesn't work in parallel, but serially, one at a time.

  (let (a b c)	; ignore this for now
    (setq a 1)
    (setq b 2)
    (setq c 3)
    (let* ((a 10)
	   (b (1+ a))
	   (c (1+ b)))
      (format t "~D ~D ~D~%" a b c)))
  prints=> 10 11 12

is equivalent to

  (let (a b c)	; ignore this for now
    (setq a 1)
    (setq b 2)
    (setq c 3)
    (let ((a 10))
      (let ((b (1+ a)))
	(let ((c (1+ b)))
	  (format t "~D ~D ~D~%" a b c)))))
  prints=> 10 11 12

is similar, but not equivalent, to

  int a, b, c;
  a = 1;
  b = 2;
  c = 3;
  a = 10;
  b = a + 1;
  c = b + 1;
  printf( "%d %d %d\n", a, b, c );

In fact, the * in LET* is sort of like the * in regular expressions:
LET* means "multiple LETs".  See
http://en.wikipedia.org/wiki/Regular_expression and
http://en.wikipedia.org/wiki/Kleene_star.

Note on "similar but not equivalent": the difference arises because
after the LET/LET*, all the variables they bind are restored to their
former values, which the above C code doesn't do.  It could, of course
-- C has block-sloped variables, too -- but I've omitted that for
clarity.

-- Larry




More information about the cl-faq mailing list