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!"
They remind me of descriptions of some kinds of people that read
slowly -- they never mastered the ability to read a whole sentence
more-or-less at once, as if hearing it, but have to laboriously puzzle
out each word, arrange them in order in their heads, and *then* they
get it.
Both groups work at the wrong level of abstraction.
People that don't get LET/COND/DO need to understand one of the basic
principles of Lisp: when writing code, if you can put "more than one"
of something, you will almost always need a sublist. In the cases
where you don't, you usually have an "implicit PROGN".
For example, LET. LET consists of a set of bindings followed by code.
(LET bindings
code1 ; implicit PROGN
code2
code3)
If you could only bind one variable at a time, it'd look like this:
(LET var val
code1
code2
code3)
But you can bind more than one variable, so you get a list of
bindings. Given that, they could've defined LET like this:
(LET (var1 val1
var2 val2
var3 val3)
code1-3)
but then you get into having to keep track of which argument you're on
(1st, 2nd, 3rd, ...) to know what role it takes. 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! That sucks. So add another set of
sublists:
(LET ((var1 val1)
(var2 val2)
(var3 val3))
code)
and it becomes much more apparent, even for this:
(LET ((a b) (c d) (e f) (g h) (i j) (k l) (m n) (o p))
code)
J is a value, not a variable!
"Where to put the parentheses" falls out just as naturally from the
basic structure of COND. COND consists of a list of alternatives.
(COND alternative1
alternative2
...)
Each alternative consists of a list of a single expression followed by
one or more expressions to execute when the first one is non-NIL:
alternative => (choice code...)
So
(COND (choice1
code1a code1b code1c) ; implicit PROGN
(choice2 code2a)
(choice3 code3a code3b))
Given the way AND and OR short-circuit, you could *almost* write a
COND with them, though you have to make COND's implicit PROGNs
explicit:
(OR (AND choice1 (PROGN code1a code1b code1c))
(AND choice2 (PROGN code2a)) ; progn not really needed here
(AND choice3 (PROGN code3a code3b)))
Here, "where to put the parentheses" pretty much leaps out at you.
This doesn't do the same thing as COND, though, since if choice1 is T
and code1c is NIL, the OR will go on to try choice2, whereas the COND
will return the NIL, so don't do this. :)
So anyway, hope this provides some fertilizer (hopefully not in the
"this is crap!" sense :) for Lisp Gardeners.
-- Larry
_______________________________________________
Gardeners mailing list
[email protected]
http://www.lispniks.com/mailman/listinfo/gardeners