Larry Clapp wrote:
> Every so often you get people on cll that say "I can never seem to
> understand LET [or COND or DO or what-have-you] -- I understand the
> various parts, but I can never remember where to put the parentheses!"

That's a good indication that something is broken.

> [...]
> Below, is J a variable to be bound or a value to be assigned?
> 
>   (LET (a b c d e f g h i j k l m n o p)
>     code)
> 
> You don't know, you have to count!

Take a look at

(LET (a b  c d  e f  g h  i j  k l  m n  o p)
  ...)

  -or-

(LET (a b
      c d
      e f
      g h
      i j
      k l
      m n
      o p)
  ...)

  -or-

(LET (a b    c d    e f    g h
      i j    k l    m n    o p)
  ...)

et cetera. Fairly obvious what's a variable name and value, isn't it?

> That sucks.  So add another set of sublists.:

No. Write a macro utility that works around the design flaw. Isn't it
the Lisp way to let the computer do the work for you? :-)

Here is an example from Graham's Common Lisp (p.83, "5.2 Context").

;; old style
(let ((x 7)
      (y 2))
  (format t "Number")
  (+ x y))

;; new style
(let (x 7
      y 2)
  (format t "Number")
  (+ x y))

Here's the macro code:

;; un-flatten a list like (a 1 b 2 c 3) into ((a 1) (b 2) (c 3))
(defun slet->let (seq)
  (if (first seq)
    `((,(first seq) ,(second seq)) ,@(slet->let (nthcdr 2 seq)))
    nil))

;; simple let
(defmacro slet (assoclist &body body)
  `(let ,(slet->let assoclist)
    ,@body))

;; simple let*
(defmacro slet* (assoclist &body body)
  `(let* ,(slet->let assoclist)
    ,@body))

I think there are easier ways to do this though. :)

> "Where to put the parentheses" falls out just as naturally from the
> basic structure of COND.  COND consists of a list of alternatives.
>
> [...]
>
> So
> 
>   (COND (choice1 
>        code1a code1b code1c)          ; implicit PROGN
>       (choice2 code2a)
>       (choice3 code3a code3b))

Could have been written as:

(COND choice1 (code1a code1b code1c)
      choice2 code2a
      choice3 (code3a code3b))

Another example from Graham's Common Lisp (p.86, "our-member").

;; old style
(defun our-member (obj lst)
  (cond ((atom lst) nil)
        ((eql (car lst) obj) lst)
        (t (our-member obj (cdr lst)))))

;; new style
(defun our-member (obj lst)
  (cond (atom lst) nil
        (eql (car lst) obj) lst
        t (our-member obj (cdr lst))))

I can't provide a macro utility for that yet. ;)

(Even McCarthy stated in [1] that "The unexpected appearance of an
interpreter tended to freeze the form of the language, and some of the
decisions made rather lightheartedly for the ``Recursive functions ...''
paper later proved unfortunate. These included the COND notation for
conditional expressions which leads to an unnecessary depth of
parentheses.")

> So anyway, hope this provides some fertilizer (hopefully not in the
> "this is crap!" sense :) for Lisp Gardeners.

Braces are Lisp's strength. Like everything else, they can be abused.
Just adding some gasoline and a spark to that fertilizer. :-)

[1] http://www-formal.stanford.edu/jmc/history/lisp/node3.html
-- 
chris c. eineke
_______________________________________________
Gardeners mailing list
[email protected]
http://www.lispniks.com/mailman/listinfo/gardeners

Reply via email to