Subject: Re: Noob: conditional let?
From: rpw3@rpw3.org (Rob Warnock)
Date: Sun, 13 Feb 2005 03:37:50 -0600
Newsgroups: comp.lang.lisp
Message-ID: <luednTh9tJtzgpLfRVn-hg@speakeasy.net>
J Krugman  <jkrugman345@yahbitoo.com> wrote:
+---------------
| I'm writing an Emacs lisp function that uses two local variables.
| The values of these local variables depend on the result of an
| elaborate test condition.  I couldn't figure anything better than
| 
|   (let ((foo (if (<elaborate-condition>) 1 2)
|         (bar (if (<elaborate-condition>) 3 4))
|     (blah-blah-blah))
| 
| ...except that "<elaborate-condition>" is much hairier-looking than it
| looks above.  This looks awful to me.  I tried improving it with
| 
|   (let* ((test (<elaborate-condition>))
|          (foo (if test 1 2))
|          (bar (if test 3 4)))
|     (blah-blah-blah))
| 
| ...but it still seems to me very clumsy to have to check test twice.
| What's the more clueful way to code this?
+---------------

Actually, I think your second version is fine [a check of a simple
variable is about the fastest test there is], but if it really
bothers you, you could always manually rewrite the LET body into
an equivalent local function, with conditional calls of it:

    (flet ((body (foo bar)
	     ...blah
		  blah
		   blah...))
      (if <elaborate-condition>
	(body 1 3)
	(body 2 4)))

In your case, it may not be worth rewriting that way, but it can
be quite useful when there are more than two possible choices to
consider and/or more than two variables in the body. e.g.:

    (flet ((body (foo bar baz gorp)
	     ...blah
		  blah
		   blah...))
      (cond
       (<test-for-variant-1>
	(body 1 3 'joe "green"))
       (<test-for-variant-2>
	(body 2 4 'phil "light blue"))
       (<test-for-variant-3>
	(body 3 7 'sally "very dark orange"))
       (t
	(body 17 9 'john-doe "while"))))


-Rob

-----
Rob Warnock			<rpw3@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607