-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 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!" > > 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 >
When I was very newbie I found it actually helped to make the implicit progns explicit and write them down, but after a week or so of coding you get used to it.. - -- +--------------------------------------------------------+ |Cyborg Animation Programmer | [EMAIL PROTECTED]| |http://badbyteblues.blogspot.com -----------------------| +--------------------------------------------------------+ -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.2.2 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFEUzuBtiwrK5pscc0RAn50AJkB4DDI5BRZZNS7W8oWgjUPewnPAwCfXsaG So0KMa1WrMCnZy6Ngr9Cz14= =lEu+ -----END PGP SIGNATURE----- _______________________________________________ Gardeners mailing list [email protected] http://www.lispniks.com/mailman/listinfo/gardeners
