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.
"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
"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
"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
"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.
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.
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
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
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
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
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
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
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)
"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")
> 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
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)
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