Anton van Straaten <anton@appsolutions.com> wrote:
+---------------
| To get a feel for the issue, try writing CASE or COND as an ordinary
| function in Lisp and see what you end up with. It's not just about the
| delaying required for each branch, it's also how you make the matching
| happen without requiring a lot of syntax repeated over and over for every
| branch. A naive attempt might look like (using backslash as pseudocode for
| a concise lambda):
|
| (cond expr
| (list (\ x match-expr1) (\ action-expr2))
| (list (\ x match-expr2) (\ action-expr2))
| ...)
...
| Next, think about performance. Since COND is now a function, when an
| expression like the above evaluates, it involves evaluating n*2 lambdas
| where n is the number of branches. This creates n*2 procedures every time
| the COND is executed...
+---------------
Well, one can handle that by making COND take exactly *three* thunks
as arguments: a test, an action, and a single "else" continuation.
Hmmm... That's really a "functional IF" (fif?), which, using Garath's
brackets for thunks, one could write as follows [deliberately using
"bad" indenting to avoid the drifting-to-the-right problem]:
(fif
[boolean-expr-1] [action-expr-1]
[(fif
[boolean-expr-2] [action-expr-2]
[(fif
[boolean-expr-2] [action-expr-2]
[(fif
[boolean-expr-2] [action-expr-2]
[otherwise-action])])])])
Oooh... That looks ugly, doesn't it? ;-}
Still, it addresses the performance issue, since while the lamdba for
the second FIF always needs to be executed (yielding a closure), the
lambdas inside it don't if the first test succeeds.
-Rob
-----
Rob Warnock <rpw3@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607