Is there a xor that operates on nil and non-nil values? I found
bitwise bit-xor and logxor in the Hyperspec, but not a "logical" xor.
I can of course define it like
(defun xor (a b)
(cond
((and a b) nil)
((not (or a b)) nil)
(t t)))
but I would prefer to use the standard name if there is one.
Tamas
Tamas Papp wrote:
> Is there a xor that operates on nil and non-nil values?
No. They said Lisp was too big so we took it out.
> I found
> bitwise bit-xor and logxor in the Hyperspec, but not a "logical" xor.
>
> I can of course define it like
>
> (defun xor (a b)
> (cond
> ((and a b) nil)
> ((not (or a b)) nil)
> (t t)))
Paid by LOC must you be.
(defun xor (c1 c2)
(if c1 (not c2) c2))
kt
--
http://www.theoryyalgebra.com/
"Algebra is the metaphysics of arithmetic." - John Ray
"As long as algebra is taught in school,
there will be prayer in school." - Cokie Roberts
"Stand firm in your refusal to remain conscious during algebra."
- Fran Lebowitz
"I'm an algebra liar. I figure two good lies make a positive."
- Tim Allen
Ken Tilton <···········@optonline.net> writes:
> Tamas Papp wrote:
>> Is there a xor that operates on nil and non-nil values?
>
> No. They said Lisp was too big so we took it out.
>
>> I found
>> bitwise bit-xor and logxor in the Hyperspec, but not a "logical" xor.
>>
>> I can of course define it like
>>
>> (defun xor (a b)
>> (cond
>> ((and a b) nil)
>> ((not (or a b)) nil)
>> (t t)))
>
> Paid by LOC must you be.
>
> (defun xor (c1 c2)
> (if c1 (not c2) c2))
Or maybe. . .
(defun xor (&rest elements)
(assert (rest elements))
(oddp (count-if #'identity elements)))
Ken Tilton <···········@optonline.net> writes:
> Tamas Papp wrote:
>> Is there a xor that operates on nil and non-nil values?
>
> No. They said Lisp was too big so we took it out.
>
>> I found
>> bitwise bit-xor and logxor in the Hyperspec, but not a "logical" xor.
>>
>> I can of course define it like
>>
>> (defun xor (a b)
>> (cond
>> ((and a b) nil)
>> ((not (or a b)) nil)
>> (t t)))
>
> Paid by LOC must you be.
>
> (defun xor (c1 c2)
> (if c1 (not c2) c2))
Thanks, this is indeed elegant.
I needed xor here because it provides a useful abstraction in the code
I am writing, but I only need the 2-argument version, not the multiple
arg one -- in fact, I haven't seen that one before and its semantics
can be tricky.
Thanks to everyone who replied,
Tamas
Tamas Papp <······@gmail.com> writes:
> Is there a xor that operates on nil and non-nil values? I found
> bitwise bit-xor and logxor in the Hyperspec, but not a "logical" xor.
>
> I can of course define it like
>
> (defun xor (a b)
> (cond
> ((and a b) nil)
> ((not (or a b)) nil)
> (t t)))
>
> but I would prefer to use the standard name if there is one.
A number of us met in Monterey, CA 2 years after the 1984 publication
of CLTL to discuss what should come next. Steele arrived with a list
of things he called "obvious" things to fix. In rough terms, the
conclusion of the meeting was that almost none of them were "obvious",
and this is how we ended up doing ANSI CL. (It also had a lot to do
with lack of good voting procedures; I've probably opined on that in
other posts already.)
Anyway, my recollection is that XOR was a classic example of the kind
of non-agreement. As I recall, the problem wasn't "do we want this",
since it seemed harmless to most people, but "should it be a special
form or a function"... OR and AND are special forms; XOR appears to be
OR-like, but only by "accident" (if you can call it that) of its
boolean pattern is it the case that you have to evaluate all of its
args in the nary case to know the answer.
And then when we got to ANSI CL, there were bigger fish to fry and I
don't know that we ever got back to this. We were more focused on
current practice at that point, and I think at the time it may be that
no Lisps had the operation.
Tamas Papp <······@gmail.com> writes:
> Is there a xor that operates on nil and non-nil values? I found
> bitwise bit-xor and logxor in the Hyperspec, but not a "logical" xor.
>
> I can of course define it like
>
> (defun xor (a b)
> (cond
> ((and a b) nil)
> ((not (or a b)) nil)
> (t t)))
>
> but I would prefer to use the standard name if there is one.
There is nothing in CL, but this XOR is a "standard" name for me...
Note that AND and OR are macros, and return generalized booleans. XOR
must evaluate all its arguments so it needs not be a macro, but on the
other hand, what should be the value of (XOR nil 1) or (XOR 1 nil)
shouldn't they be 1? Perhaps not. This is a more delicate question,
I suppose that's why XOR is not in CL.
--
__Pascal Bourguignon__ http://www.informatimago.com/
NOTE: The most fundamental particles in this product are held
together by a "gluing" force about which little is currently known
and whose adhesive power can therefore not be permanently
guaranteed.
Pascal Bourguignon <···@informatimago.com> writes:
> > (defun xor (a b) ...)
>
> There is nothing in CL, but this XOR is a "standard" name for me...
>
> Note that AND and OR are macros, and return generalized booleans. XOR
> must evaluate all its arguments so it needs not be a macro, but on the
> other hand, what should be the value of (XOR nil 1) or (XOR 1 nil)
> shouldn't they be 1? Perhaps not. This is a more delicate question,
> I suppose that's why XOR is not in CL.
The problems begin to arise if you want to attach semantics to XOR
with variable arity that all people in a room agree on.
E.g. is (XOR A B C D)
equal to more or less (reduce #'xor (list A B C D))
or
true if and only if exactly /one/ argument is non NIL.
(Note that XOR could short-circuit in the latter case, and would hence
have to be implemented as a macro.)
-T.
From: Jeronimo Pellegrini
Subject: Re: is there a xor?
Date:
Message-ID: <f9q3b5$fpc$1@aioe.org>
On 2007-08-13, Tobias C. Rittweiler <···@freebits.de.invalid> wrote:
> The problems begin to arise if you want to attach semantics to XOR
> with variable arity that all people in a room agree on.
>
> E.g. is (XOR A B C D)
>
> equal to more or less (reduce #'xor (list A B C D))
>
> or
>
> true if and only if exactly /one/ argument is non NIL.
>
> (Note that XOR could short-circuit in the latter case, and would hence
> have to be implemented as a macro.)
How can you tell if only one argument evaluates to non NIL if you
don't evaluate all of them?
Think for example: (XOR A B C D E F) with A=1, F=1 and the rest NIL...
J.
Jeronimo Pellegrini <···@aleph0.info> writes:
> On 2007-08-13, Tobias C. Rittweiler <···@freebits.de.invalid> wrote:
>
> > E.g. is (XOR A B C D)
> >
> > equal to more or less (reduce #'xor (list A B C D))
> >
> > or
> >
> > true if and only if exactly /one/ argument is non NIL.
> >
> > (Note that XOR could short-circuit in the latter case, and would hence
> > have to be implemented as a macro.)
>
> How can you tell if only one argument evaluates to non NIL if you
> don't evaluate all of them?
(xor A B t C t D E)
If XOR short-circuits, then D and E don't need to be evaluated as it's
already obvious that the whole form cannot possible become true.
-T.
From: Jeronimo Pellegrini
Subject: Re: is there a xor?
Date:
Message-ID: <f9qb1r$4jl$1@aioe.org>
On 2007-08-13, Tobias C. Rittweiler <···@freebits.de.invalid> wrote:
> Jeronimo Pellegrini <···@aleph0.info> writes:
>
>> On 2007-08-13, Tobias C. Rittweiler <···@freebits.de.invalid> wrote:
>>
>> > E.g. is (XOR A B C D)
>> >
>> > equal to more or less (reduce #'xor (list A B C D))
>> >
>> > or
>> >
>> > true if and only if exactly /one/ argument is non NIL.
>> >
>> > (Note that XOR could short-circuit in the latter case, and would hence
>> > have to be implemented as a macro.)
>>
>> How can you tell if only one argument evaluates to non NIL if you
>> don't evaluate all of them?
>
> (xor A B t C t D E)
>
> If XOR short-circuits, then D and E don't need to be evaluated as it's
> already obvious that the whole form cannot possible become true.
Yes, of course! Sorry about the noise...
J.
On Aug 13, 2:12 am, Tamas Papp <······@gmail.com> wrote:
> Is there a xor that operates on nil and non-nil values? I found
> bitwise bit-xor and logxor in the Hyperspec, but not a "logical" xor.
The and and or logical operators are macros which perform conditional
evaluation of forms. Moreover, they can take more than two arguments.
For instance:
(and (input-available) (output-buffers-available) (process-and-
foward-data))
will not evaluate (process-and-forward-data) unless both (input-
available) and (output-buffers-available) yield true. The or operator
is often used to return the value of the first form which returns
other than nil, and evaluate no more forms after that one. E.g.
(let ((course-of-action (or (expert-one) (expert-two) (default-
strategy))))
...)
Here, we take the ``course of action'' object from the (expert-one)
form, if it returns something other than nil. Otherwise, we try the
(expert-two) form. If that yields nil, we try default-strategy (which
perhaps is set up to always return something, ensuring that we have a
couse of action).
An xor operator wouldn't fit neatly among these. A ternary or n-ary
xor doesn't make much sense (although definitions of it exist), and
xor must evaluate all of its arguments in order to produce an answer.
> I can of course define it like
>
> (defun xor (a b)
> (cond
> ((and a b) nil)
> ((not (or a b)) nil)
> (t t)))
Alternatives:
;; A or B, but not both A and B.
(and (or a b) (not (and a b)))
or:
;; Either A but not B, or A but not A.
(or (and a (not b)) (and (not a) b))
Finally, note that the way you have used COND in the above example
corresponds to the (negated) OR operator!!! Your pattern is:
(cond (c1 nil) (c2 nil) ... (cn nil) (t t))
The OR operator (and c1 c2 ... cn) corresponds to:
(cond (c1 c1) (c2 c2) ... (cn cn) (t nil))
Wrap a NOT around this expression and effectively have the previous
one. So your function can be rewritten:
(not (or (and a b) (not (or a b)))
Using De Morgan's, we can distribute the main NOT into the OR, by
changing it to an AND, and negating its clauses:
(and (not (and a b)) (or a b))
In general, if you are finding yourself writing a COND where the
successive return values are all just NIL or T, maybe you want to be
somehow using AND or OR. :)