From: Don Geddis
Subject: COND Style: clever or obfuscated?
Date: 
Message-ID: <m3adfag830.fsf@maul.geddis.org>
I had some code roughly like this:

        (WHEN (OR (AND A X)
                  (AND B Y)
                  (AND C Z)
                  ... )
           ...do-something... )

It happens that A, B, C, ... are mutually exclusive.  It seemed like a waste
to me to run the B, C, ... tests if A were true, so I changed the code to

        (WHEN (COND (A X)
                    (B Y)
                    (C Z)
                    ... )
              ...do-something... )

Any style opinions about this?  It seems unusual to me to use COND solely
in order to make a short-circuiting OR-AND test, but on the other hand it
does coincidentally mirror the logic of my situation.

I can't decide whether this is mildly clever, or more confusing than it is
worth.  (In case it changes your answer: computing A, B, C, ... is not
expensive.  If they were very expensive, one might prefer awkward-but-fast
to simple-but-slow.  But that's not my situation.)

        -- Don

P.S. I guess another alternative is IF-then-else chains

        (WHEN (IF A X
                    (IF B Y
                          (IF C Z
                                (IF ...) )))
              ...do-something... )

That's probably my least favorite of the three, due to the excessive
indentations.
_______________________________________________________________________________
Don Geddis                    http://don.geddis.org              ···@geddis.org
When cryptography is outlawed, bayl bhgynjf jvyy unir cevinpl.

From: Geoffrey Summerhayes
Subject: Re: COND Style: clever or obfuscated?
Date: 
Message-ID: <Xe9ia.1502$DD6.388342@news20.bellglobal.com>
"Don Geddis" <···@geddis.org> wrote in message ···················@maul.geddis.org...
> I had some code roughly like this:
>
>         (WHEN (OR (AND A X)
>                   (AND B Y)
>                   (AND C Z)
>                   ... )
>            ...do-something... )
>
> It happens that A, B, C, ... are mutually exclusive.  It seemed like a waste
> to me to run the B, C, ... tests if A were true, so I changed the code to
>
>         (WHEN (COND (A X)
>                     (B Y)
>                     (C Z)
>                     ... )
>               ...do-something... )
>
> Any style opinions about this?  It seems unusual to me to use COND solely
> in order to make a short-circuiting OR-AND test, but on the other hand it
> does coincidentally mirror the logic of my situation.

OR and AND are macros, not functions. They already short-circuit.

From CLHS

or evaluates each form, one at a time, from left to right. The evaluation of
all forms terminates when a form evaluates to true (i.e., something other than nil).

The macro and evaluates each form one at a time from left to right. As soon as any
form evaluates to nil, and returns nil without evaluating the remaining forms. If
all forms but the last evaluate to true values, and returns the results produced by
evaluating the last form.

--
Geoff
From: Peter Seibel
Subject: Re: COND Style: clever or obfuscated?
Date: 
Message-ID: <m3pto6vjo7.fsf@localhost.localdomain>
"Geoffrey Summerhayes" <·············@hotmail.com> writes:

> "Don Geddis" <···@geddis.org> wrote in message ···················@maul.geddis.org...
> > I had some code roughly like this:
> >
> >         (WHEN (OR (AND A X)
> >                   (AND B Y)
> >                   (AND C Z)
> >                   ... )
> >            ...do-something... )
> >
> > It happens that A, B, C, ... are mutually exclusive.  It seemed like a waste
> > to me to run the B, C, ... tests if A were true, so I changed the code to
> >
> >         (WHEN (COND (A X)
> >                     (B Y)
> >                     (C Z)
> >                     ... )
> >               ...do-something... )
> >
> > Any style opinions about this?  It seems unusual to me to use COND solely
> > in order to make a short-circuiting OR-AND test, but on the other hand it
> > does coincidentally mirror the logic of my situation.
> 
> OR and AND are macros, not functions. They already short-circuit.

I think the Don wants to short circuit when A is true but X is false.
Because A, B, and C happen to be mutually exclusive, if A is true but
X is false (and thus (AND A X) is false, there's no point in
evaluating B and C. But the OR, having failed on (AND A X) will keep
going trying (AND B Y) and (AND C Z) (each of which will be false
because B and C are false.

The COND expression, on the other hand, only evaluates A and X when A
is true and X is false.

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

  The intellectual level needed   for  system design is  in  general
  grossly  underestimated. I am  convinced  more than ever that this
  type of work is very difficult and that every effort to do it with
  other than the best people is doomed to either failure or moderate
  success at enormous expense. --Edsger Dijkstra
From: Geoffrey Summerhayes
Subject: Re: COND Style: clever or obfuscated?
Date: 
Message-ID: <uthia.1585$DD6.425133@news20.bellglobal.com>
"Peter Seibel" <·····@javamonkey.com> wrote in message ···················@localhost.localdomain...
> "Geoffrey Summerhayes" <·············@hotmail.com> writes:
>
> > OR and AND are macros, not functions. They already short-circuit.
>
> I think the Don wants to short circuit when A is true but X is false.
> Because A, B, and C happen to be mutually exclusive, if A is true but
> X is false (and thus (AND A X) is false, there's no point in
> evaluating B and C. But the OR, having failed on (AND A X) will keep
> going trying (AND B Y) and (AND C Z) (each of which will be false
> because B and C are false.
>
> The COND expression, on the other hand, only evaluates A and X when A
> is true and X is false.
>

Oh damn, of course that's what he meant. Read it too quickly, I'll blame
lack of sleep. :-)

COND is certainly the way to go.

--
Geoff
From: Kalle Olavi Niemitalo
Subject: Re: COND Style: clever or obfuscated?
Date: 
Message-ID: <87he9ilqa7.fsf@Astalo.kon.iki.fi>
"Geoffrey Summerhayes" <·············@hotmail.com> writes:

> "Don Geddis" <···@geddis.org> wrote in message ···················@maul.geddis.org...
> >         (WHEN (OR (AND A X)
> >                   (AND B Y)
> >                   (AND C Z)
> >                   ... )
> >            ...do-something... )

> OR and AND are macros, not functions. They already short-circuit.

I believe the OP was thinking of the case when A is true but X
is false.  As A, B and C are mutually exclusive, B and C will be
false; then, each AND returns false, and the OR does not
short-circuit.  With COND, one can avoid evaluating B and C.

I like the COND version.
From: Kent M Pitman
Subject: Re: COND Style: clever or obfuscated?
Date: 
Message-ID: <sfwpto6qq6i.fsf@shell01.TheWorld.com>
Don Geddis <···@geddis.org> writes:

>         (WHEN (COND (A X)
>                     (B Y)
>                     (C Z)
>                     ... )
>               ...do-something... )
> 
> Any style opinions about this?  It seems unusual to me to use COND solely
> in order to make a short-circuiting OR-AND test, but on the other hand it
> does coincidentally mirror the logic of my situation.

We learn style rules in modular fashion so that they will snap into new
situations. :)

It's rare to have a conditional conditional, but the same old style
rules apply here as anywhere, I think.
From: Kenny Tilton
Subject: Re: COND Style: clever or obfuscated?
Date: 
Message-ID: <3E8994DB.2050208@nyc.rr.com>
Don Geddis wrote:
> I had some code roughly like this:
> 
>         (WHEN (OR (AND A X)
>                   (AND B Y)
>                   (AND C Z)
>                   ... )
>            ...do-something... )
> 
> It happens that A, B, C, ... are mutually exclusive.  It seemed like a waste
> to me to run the B, C, ... tests if A were true, so I changed the code to
> 
>         (WHEN (COND (A X)
>                     (B Y)
>                     (C Z)
>                     ... )
>               ...do-something... )
> 
> Any style opinions about this?  It seems unusual to me to use COND solely
> in order to make a short-circuiting OR-AND test, but on the other hand it
> does coincidentally mirror the logic of my situation.

a number of respondents missed the subtlety that X might be false while 
A was true causing unnecessary evaluation of B, so there is your answer: 
use COND.

>   It seems unusual to me to use COND solely
 > in order to make a short-circuiting OR-AND test, but on the other hand it
 > does coincidentally mirror the logic of my situation.

OK, now turn that paragraph around: OR-AND does not mirror your logic. 
(You are done, that is Bad Thing.) Not mirroring your logic, it:

- consitutes false self-documentation
- can cause needless evaluation
- may yield a solid bug when this code has to be modified (a trap has 
been set).

So it is not "soley...short-circuiting OR-AND", it is a significant 
improvement to the readability and maintainability of your code.

> P.S. I guess another alternative is IF-then-else chains
> 
>         (WHEN (IF A X
>                     (IF B Y
>                           (IF C Z
>                                 (IF ...) )))
>               ...do-something... )
> 

Looks like COND to me. :)


-- 

  kenny tilton
  clinisys, inc
  http://www.tilton-technology.com/
  ---------------------------------------------------------------
"Cells let us walk, talk, think, make love and realize
  the bath water is cold." -- Lorraine Lee Cudmore
From: Adam Warner
Subject: Re: COND Style: clever or obfuscated?
Date: 
Message-ID: <pan.2003.04.01.14.52.05.244893@consulting.net.nz>
Hi Kenny Tilton,

> Don Geddis wrote:
>> I had some code roughly like this:
>> 
>>         (WHEN (OR (AND A X)
>>                   (AND B Y)
>>                   (AND C Z)
>>                   ... )
>>            ...do-something... )
>> 
>> It happens that A, B, C, ... are mutually exclusive.  It seemed like a waste
>> to me to run the B, C, ... tests if A were true, so I changed the code to
>> 
>>         (WHEN (COND (A X)
>>                     (B Y)
>>                     (C Z)
>>                     ... )
>>               ...do-something... )
>> 
>> Any style opinions about this?  It seems unusual to me to use COND solely
>> in order to make a short-circuiting OR-AND test, but on the other hand it
>> does coincidentally mirror the logic of my situation.
> 
> a number of respondents missed the subtlety that X might be false while 
> A was true causing unnecessary evaluation of B, so there is your answer: 
> use COND.

Indeed. I'm sorry to have missed this. Don's solution is clever.

It's no more obfuscated than using the return value of OR. And that's a
Lispy thing to do.

Regards,
Adam
From: Chris Perkins
Subject: Re: COND Style: clever or obfuscated?
Date: 
Message-ID: <6cb6c81f.0304011425.2a068092@posting.google.com>
Use the COND version, but maybe wrap the (COND <pair> <pair> <pair>)
logic in macro named "test-pair" or something.  Then you get shortcut
and the readability.   (when (test-pairs a x b y c z)....

Chris
From: Chris Perkins
Subject: Re: COND Style: clever or obfuscated?
Date: 
Message-ID: <6cb6c81f.0304011431.74b42143@posting.google.com>
....or instead of a macro maybe just a comment in the code would suffice.

Chris
From: Adam Warner
Subject: Re: COND Style: clever or obfuscated?
Date: 
Message-ID: <pan.2003.04.01.08.12.58.674057@consulting.net.nz>
Hi Don Geddis,

> I had some code roughly like this:
> 
>         (WHEN (OR (AND A X)
>                   (AND B Y)
>                   (AND C Z)
>                   ... )
>            ...do-something... )
> 
> It happens that A, B, C, ... are mutually exclusive.  It seemed like a waste
> to me to run the B, C, ... tests if A were true, so I changed the code to
> 
>         (WHEN (COND (A X)
>                     (B Y)
>                     (C Z)
>                     ... )
>               ...do-something... )
> 
> Any style opinions about this?  It seems unusual to me to use COND solely
> in order to make a short-circuiting OR-AND test, but on the other hand it
> does coincidentally mirror the logic of my situation.

Nice dilemma. But I don't see how you have anything to worry about:

* (or (and t) (print "evaluated") (print "evaluated"))

t
* (or (and nil) (print "evaluated") (print "evaluated"))  

"evaluated" 
"evaluated"

Notice how the last two forms didn't evaluate when the first AND was true?

Even in the second example the last form didn't evaluate. "evaluated" is
a non-nil return value. This makes it clearer:

* (or (and nil) (print "evaluated") (print "not evaluated"))

"evaluated" 
"evaluated"

Regards,
Adam
From: Drew McDermott
Subject: Re: COND Style: clever or obfuscated?
Date: 
Message-ID: <b6dkg6$4c5$1@news.ycc.yale.edu>
Don Geddis wrote:
> 
> It happens that A, B, C, ... are mutually exclusive.  It seemed like a waste
> to me to run the B, C, ... tests if A were true, so I changed the code to
> 
>         (WHEN (COND (A X)
>                     (B Y)
>                     (C Z)
>                     ... )
>               ...do-something... )
> 
> Any style opinions about this? 

I would write (cond ((cond (a x) (b y) (c z))
                      ...))

I never use 'when' and 'if' and 'unless' because they're so clumsy when 
you have to change the "else" structure.  McCarthy and company stumbled 
on the perfect syntax for conditionals when they looked for a 
parenthesized version of

       t1 -> e1; t2 -> e2; ...; tN -> eN

It's odd that people apologize for 'cond' instead of bragging about it.

     -- Drew McDermott
From: Kenny Tilton
Subject: Re: COND Style: clever or obfuscated?
Date: 
Message-ID: <3E8A9B3C.4080907@nyc.rr.com>
Drew McDermott wrote:
> Don Geddis wrote:
> 
>>
>> It happens that A, B, C, ... are mutually exclusive.  It seemed like a 
>> waste
>> to me to run the B, C, ... tests if A were true, so I changed the code to
>>
>>         (WHEN (COND (A X)
>>                     (B Y)
>>                     (C Z)
>>                     ... )
>>               ...do-something... )
>>
>> Any style opinions about this? 
> 
> 
> I would write (cond ((cond (a x) (b y) (c z))
>                      ...))
> 
> I never use 'when' and 'if' and 'unless' because they're so clumsy...

whoa, hardcore lisper passing...

>   McCarthy and company stumbled
> on the perfect syntax for conditionals when they looked for a 
> parenthesized version of
> 
>       t1 -> e1; t2 -> e2; ...; tN -> eN
> 
> It's odd that people apologize for 'cond' instead of bragging about it.

i read somewhere that lisp got invented because some other language 
group JMcC was involved with would not go for COND. it's cool that 
something so obvious in hindsight was so controversial it needed a new 
language to get adopted.

now if we only had the cobol EVALUATE...

-- 

  kenny tilton
  clinisys, inc
  http://www.tilton-technology.com/
  ---------------------------------------------------------------
"Cells let us walk, talk, think, make love and realize
  the bath water is cold." -- Lorraine Lee Cudmore
From: Espen Vestre
Subject: Re: COND Style: clever or obfuscated?
Date: 
Message-ID: <kwbrzps3ie.fsf@merced.netfonds.no>
Don Geddis <···@geddis.org> writes:

> I had some code roughly like this:
> 
>         (WHEN (OR (AND A X)
>                   (AND B Y)
>                   (AND C Z)
>                   ... )
>            ...do-something... )

Here's the logician's solution ;-):

(unless (and (not (and a x))
             (not (and b y))
             (not (and c z)))
    ....do-something....)

(In real life, I've chosen your cond-version serveral times. I find
 it perfectly o.k.!)
-- 
  (espen)
From: Coby Beck
Subject: Re: COND Style: clever or obfuscated?
Date: 
Message-ID: <b6ebm6$22nq$1@otis.netspace.net.au>
"Espen Vestre" <·····@*do-not-spam-me*.vestre.net> wrote in message
···················@merced.netfonds.no...
> Don Geddis <···@geddis.org> writes:
>
> > I had some code roughly like this:
> >
> >         (WHEN (OR (AND A X)
> >                   (AND B Y)
> >                   (AND C Z)
> >                   ... )
> >            ...do-something... )
>
> Here's the logician's solution ;-):
>
> (unless (and (not (and a x))
>              (not (and b y))
>              (not (and c z)))
>     ....do-something....)
>

I was trying to work it out something like this too (until my brain started
to hurt) but the above won't do the trick, I think.  In the spec, if A is
true and X is false, the whole thing should be false but not in the above.

What we need now is a mathmatician to chime in with a proof that it is
actually impossible to do this with only combinations of and's or's and
not's without storing some intermediate result or evaluating something
unnecesarily.

Nested if's is the only way and cond is a nice expression for that.

--
Coby Beck
(remove #\Space "coby 101 @ bigpond . com")
From: Don Geddis
Subject: Re: COND Style: clever or obfuscated?
Date: 
Message-ID: <m33cl09dmo.fsf@maul.geddis.org>
> Don Geddis <···@geddis.org> writes:
> > I had some code roughly like this:
> >         (WHEN (OR (AND A X)
> >                   (AND B Y)
> >                   (AND C Z)
> >                   ... )
> >            ...do-something... )

Espen Vestre <·····@*do-not-spam-me*.vestre.net> writes:
> Here's the logician's solution ;-):
> (unless (and (not (and a x))
>              (not (and b y))
>              (not (and c z)))
>     ....do-something....)

Funny joke, but just to be clear: my original dilemma was to avoid
executing the B and C tests (which, from domain knowledge, I knew would
be false) in the case when A was true but X was false.  Your UNLESS form
is pretty much computationally equalivalent to my WHEN.  (I take it you
were just making an obfuscating joke, perhaps appropriate to the subject...)

> (In real life, I've chosen your cond-version serveral times. I find
>  it perfectly o.k.!)

Yup, that seems the most popular.  Thanks.
_______________________________________________________________________________
Don Geddis                    http://don.geddis.org              ···@geddis.org
From: Espen Vestre
Subject: Re: COND Style: clever or obfuscated?
Date: 
Message-ID: <kwel4jonkw.fsf@merced.netfonds.no>
Don Geddis <···@geddis.org> writes:

> be false) in the case when A was true but X was false.  Your UNLESS form
> is pretty much computationally equalivalent to my WHEN.  (I take it you
> were just making an obfuscating joke, perhaps appropriate to the subject...)

Sure. (I didn't work it out in detail, but as far as I can tell it
does _exactly_ the same thing, computationally, since OR will
short-circuit when it finds a true statement, and AND will
short-circuit when it finds a false statement, so by negating on the
inside and outside, you short-circuit exactly in the same situations)

If your original concern was that you wanted to be 'logically kosher',
there's IMHO nothing wrong about regarding COND as logical operator:

Logically, 

(cond (a x) (b y) (c z))

can be regarded as shorthand for:

(or (and a x)
    (and (not a) b y)
    (and (not a) (not b) c z))

I.e. it's the original OR-statement augmented with (parts of) your
mutual exclusion constraint.

(btw, I've sometimes implemented boolean functions as generic functions
 with several eql-methods on symbols, which really is the same thing
 as the cond-solution, the cond-statement is just hidden in the CLOS
 machinery.)
-- 
  (espen)
From: Brian Palmer
Subject: Re: COND Style: clever or obfuscated?
Date: 
Message-ID: <0wh7kabq0jb.fsf@rescomp.Stanford.EDU>
Don Geddis <···@geddis.org> writes:
 
> P.S. I guess another alternative is IF-then-else chains
> 
>         (WHEN (IF A X
>                     (IF B Y
>                           (IF C Z
>                                 (IF ...) )))
>               ...do-something... )
> 
> That's probably my least favorite of the three, due to the excessive
> indentations.

Well, I think the cond technique is clever, but not obvious. (Then
again, I'm not much of a lisp programmer). However, I wouldn't indent
the if-then-else chain quite so much:

(when (if a
	  x
	(if b
	    y
	  (if c
	      z
	    (IF ...) )))
  ...do-something... )

that's using ilisp's default indentation, when you use lower-case
'if'. 

-- 
If you want divine justice, die.
                  -- Nick Seldon