From: Tamas Papp
Subject: is there a xor?
Date: 
Message-ID: <87d4xr7q8a.fsf@pu100877.student.princeton.edu>
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

From: Ken Tilton
Subject: Re: is there a xor?
Date: 
Message-ID: <efYvi.10$sN1.8@newsfe12.lga>
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
From: Rob St. Amant
Subject: Re: is there a xor?
Date: 
Message-ID: <f9pk5i$ees$1@blackhelicopter.databasix.com>
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)))
From: Ken Tilton
Subject: Re: is there a xor?
Date: 
Message-ID: <7AYvi.21$sN1.0@newsfe12.lga>
Rob St. Amant wrote:
> 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)))

Paid by FASL size be must you. kzo

PQ(8): ;; disassembly of #<Function XOR>
;; formals: C1 C2

;; code start: #x1f62415c:
    0: 83 f9 02  cmpl	ecx,$2
    3: 74 03      jz	8
    5: ff 57 8b  call	*[edi-117]     ; SYS::TRAP-WNAERR
    8: 80 7f cb 00 cmpb	[edi-53],$0 ; SYS::C_INTERRUPT-PENDING
   12: 74 03      jz	17
   14: ff 57 87  call	*[edi-121]     ; SYS::TRAP-SIGNAL-HIT
   17: 3b f8      cmpl	edi,eax
   19: 74 0c      jz	33
   21: 3b fa      cmpl	edi,edx
   23: 75 0d      jnz	38
   25: 8d 47 c2  leal	eax,[edi-62]   ; T
   28: f8          clc
   29: 8b 75 fc  movl	esi,[ebp-4]
   32: c3          ret
   33: 8b c2      movl	eax,edx
   35: f8          clc
   36: eb f7      jmp	29
   38: 8b c7      movl	eax,edi
   40: f8          clc
   41: eb f2      jmp	29
   43: 90          nop

PQ(7): ;; disassembly of #<Function XOROB>
;; formals: &REST ELEMENTS
;; constant vector:
0: (REST ELEMENTS)
1: EXCL::ASSERT-1
2: IDENTITY
3: COUNT-IF

;; code start: #x2d7d706c:
    0: 55          pushl	ebp
    1: 8b ec      movl	ebp,esp
    3: 83 ec 40  subl	esp,$64
    6: 89 75 fc  movl	[ebp-4],esi
    9: 89 5d e4  movl	[ebp-28],ebx
   12: 39 a3 be 00 cmpl	[ebx+190],esp
       00 00
   18: 76 03      jbe	23
   20: ff 57 43  call	*[edi+67]      ; SYS::TRAP-STACK-OVFL
   23: 89 45 08  movl	[ebp+8],eax
   26: 89 55 0c  movl	[ebp+12],edx
   29: 8d 45 08  leal	eax,[ebp+8]
   32: 89 5d e8  movl	[ebp-24],ebx
   35: 8b 5d e4  movl	ebx,[ebp-28]
   38: ff 97 67 02 call	*[edi+615]   ; SYS::RESTIFY2
       00 00
   44: 8b d8      movl	ebx,eax
   46: 80 7f cb 00 cmpb	[edi-53],$0 ; SYS::C_INTERRUPT-PENDING
   50: 74 03      jz	55
   52: ff 57 87  call	*[edi-121]     ; SYS::TRAP-SIGNAL-HIT
   55: eb 20      jmp	89
   57: 8b d7      movl	edx,edi
   59: 8b 46 12  movl	eax,[esi+18]   ; (REST ELEMENTS)
   62: 83 c4 14  addl	esp,$20
   65: 57          pushl	edi
   66: 57          pushl	edi
   67: 57          pushl	edi
   68: 52          pushl	edx
   69: 50          pushl	eax
   70: 8b 5e 16  movl	ebx,[esi+22]   ; EXCL::ASSERT-1
   73: b1 05      movb	cl,$5
   75: ff d7      call	*edi
   77: 80 7f cb 00 cmpb	[edi-53],$0 ; SYS::C_INTERRUPT-PENDING
   81: 74 03      jz	86
   83: ff 57 87  call	*[edi-121]     ; SYS::TRAP-SIGNAL-HIT
   86: 8b 5d dc  movl	ebx,[ebp-36]   ; ELEMENTS
   89: 8b c3      movl	eax,ebx
   91: 89 5d dc  movl	[ebp-36],ebx   ; ELEMENTS
   94: 89 5d e8  movl	[ebp-24],ebx
   97: 8b 5d e4  movl	ebx,[ebp-28]
  100: ff 57 5b  call	*[edi+91]      ; SYS::QCDR
  103: 3b f8      cmpl	edi,eax
  105: 74 ce      jz	57
  107: 8b 5e 1a  movl	ebx,[esi+26]   ; IDENTITY
  110: 8b 43 f5  movl	eax,[ebx-11]
  113: 8b 55 dc  movl	edx,[ebp-36]   ; ELEMENTS
  116: 8b 5e 1e  movl	ebx,[esi+30]   ; COUNT-IF
  119: ff 57 27  call	*[edi+39]      ; SYS::TRAMP-TWO
  122: 8b 9f b3 fc movl	ebx,[edi-845]       ; EXCL::LOGAND_2OP
       ff ff
  128: ba 04 00 00 movl	edx,$4       ; 1
       00
  133: ff 57 27  call	*[edi+39]      ; SYS::TRAMP-TWO
  136: 83 f8 04  cmpl	eax,$4
  139: 8b c7      movl	eax,edi
  141: 75 03      jnz	146
  143: 8d 47 c2  leal	eax,[edi-62]   ; T
  146: f8          clc
  147: 8b 5d dc  movl	ebx,[ebp-36]   ; ELEMENTS
  150: c9          leave
  151: 8b 75 fc  movl	esi,[ebp-4]
  154: c3          ret
  155: 90          nop


-- 
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
From: Tamas Papp
Subject: Re: is there a xor?
Date: 
Message-ID: <87ir7j1s1f.fsf@pu100877.student.princeton.edu>
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
From: Kent M Pitman
Subject: Re: is there a xor?
Date: 
Message-ID: <u8x8fvam3.fsf@nhplace.com>
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.
From: Pascal Bourguignon
Subject: Re: is there a xor?
Date: 
Message-ID: <87tzr3ehs2.fsf@informatimago.com>
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.
From: Tobias C. Rittweiler
Subject: Re: is there a xor?
Date: 
Message-ID: <87ps1rd1l0.fsf@freebits.de>
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.
From: Tobias C. Rittweiler
Subject: Re: is there a xor?
Date: 
Message-ID: <878x8fcpg9.fsf@freebits.de>
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.
From: Kaz Kylheku
Subject: Re: is there a xor?
Date: 
Message-ID: <1187033349.705276.93490@22g2000hsm.googlegroups.com>
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. :)