Keith Hodges wrote:
true xor: [ true ] => true
I don't think it's a bug. Unless you want to sprinkle lots of code with type tests, the result is whatever the implementation says, in this case:
xor: aBoolean "Exclusive OR. Answer true if the receiver is not equivalent to aBoolean."
^(self == aBoolean) not
You could equally complain about
true & "anything"
answering the argument instead of raising an error.
Cheers, - Andreas
On Tue, Mar 24, 2009 at 2:22 PM, Andreas Raab andreas.raab@gmx.de wrote:
Keith Hodges wrote:
true xor: [ true ] => true
I don't think it's a bug. Unless you want to sprinkle lots of code with type tests, the result is whatever the implementation says, in this case:
xor: aBoolean "Exclusive OR. Answer true if the receiver is not equivalent to aBoolean."
^(self == aBoolean) not
IMHO Should be:
xor: aBoolean "Exclusive OR. Answer true if the receiver is not equivalent to aBoolean."
^(self = aBoolean value) not
With Object>>value returning self.
Gulik.
1) #xor: should not take a block as argument. Rationale: - the block would ALWAYS have to be evaluated - block arguments are either for repeated evaluation, or condiitonal evaluation... This is not the case here, so the need of a block argument vanishes...
2) #xor: argument should be a Boolean, but here no guard is made.
We could eventually add: aBoolean isBoolean ifFalse; [self error: 'xor must take a boolean as argument']
Or if we want to later extend to some other class: True>>xor: aBoolean ^aBoolean xorTrue False>>xor: aBoolean ^aBoolean xorFalse True>>xorTrue ^false True>>xorFalse ^self False>>xorTrue ^true False>>xorFalse ^self
MySymbolicBooleanClass>>xorTrue ^SymbolicXorOperation with: self with: true
I'm not sure whether we need to protect or not... I tend to avoid over-protecting code. As long as a debugger opens, I claim protecting is void... But here, I don't like a false program proceeding without a Notifier....
Nicolas
2009/3/24 Keith Hodges keith_hodges@yahoo.co.uk
true xor: [ true ] => true
discuss
Keith
Nicolas Cellier wrote:
- #xor: should not take a block as argument.
Rationale:
- the block would ALWAYS have to be evaluated
- block arguments are either for repeated evaluation, or condiitonal
evaluation... This is not the case here, so the need of a block argument vanishes...
True!
- #xor: argument should be a Boolean, but here no guard is made.
We could eventually add: aBoolean isBoolean ifFalse; [self error: 'xor must take a boolean as argument']
Or if we want to later extend to some other class: True>>xor: aBoolean ^aBoolean xorTrue False>>xor: aBoolean ^aBoolean xorFalse True>>xorTrue ^false True>>xorFalse ^self False>>xorTrue ^true False>>xorFalse ^self
Beautiful!
MySymbolicBooleanClass>>xorTrue ^SymbolicXorOperation with: self with: true
I'm not sure whether we need to protect or not... I tend to avoid over-protecting code. As long as a debugger opens, I claim protecting is void... But here, I don't like a false program proceeding without a Notifier....
Agreed.
Nicolas
Cheers, Juan Vuletich
On Mon, Mar 23, 2009 at 6:32 PM, Nicolas Cellier < nicolas.cellier.aka.nice@gmail.com> wrote:
- #xor: should not take a block as argument.
Rationale:
- the block would ALWAYS have to be evaluated
- block arguments are either for repeated evaluation, or condiitonal
evaluation... This is not the case here, so the need of a block argument vanishes...
- #xor: argument should be a Boolean, but here no guard is made.
We could eventually add: aBoolean isBoolean ifFalse; [self error: 'xor must take a boolean as argument']
Or if we want to later extend to some other class: True>>xor: aBoolean ^aBoolean xorTrue False>>xor: aBoolean ^aBoolean xorFalse True>>xorTrue ^false True>>xorFalse ^self False>>xorTrue ^true False>>xorFalse ^self
I think just
True>>xor: aBoolean ^aBoolean not
False>>xor: aBoolean ^aBoolean
and then leave subsequent usage to catch possible type errors; e.g. (false xor: #blah) ifTrue: ... will raise a mustBeBoolean error.
MySymbolicBooleanClass>>xorTrue
^SymbolicXorOperation with: self with: true
I'm not sure whether we need to protect or not... I tend to avoid over-protecting code. As long as a debugger opens, I claim protecting is void...
+1
But here, I don't like a false program proceeding without a Notifier....
Nicolas
2009/3/24 Keith Hodges keith_hodges@yahoo.co.uk
true xor: [ true ] => true
discuss
Keith
Eliot Miranda wrote:
On Mon, Mar 23, 2009 at 6:32 PM, Nicolas Cellier <nicolas.cellier.aka.nice@gmail.com mailto:nicolas.cellier.aka.nice@gmail.com> wrote:
1) #xor: should not take a block as argument. Rationale: - the block would ALWAYS have to be evaluated - block arguments are either for repeated evaluation, or condiitonal evaluation... This is not the case here, so the need of a block argument vanishes... 2) #xor: argument should be a Boolean, but here no guard is made. We could eventually add: aBoolean isBoolean ifFalse; [self error: 'xor must take a boolean as argument'] Or if we want to later extend to some other class: True>>xor: aBoolean ^aBoolean xorTrue False>>xor: aBoolean ^aBoolean xorFalse True>>xorTrue ^false True>>xorFalse ^self False>>xorTrue ^true False>>xorFalse ^self
I think just
True>>xor: aBoolean ^aBoolean not
False>>xor: aBoolean ^aBoolean
and then leave subsequent usage to catch possible type errors; e.g. (false xor: #blah) ifTrue: ... will raise a mustBeBoolean error.
Oh, that's even better!
Thanks, Juan Vuletich
"Eliot" == Eliot Miranda eliot.miranda@gmail.com writes:
Eliot> I think just
True> xor: aBoolean Eliot> ^aBoolean not
False> xor: aBoolean Eliot> ^aBoolean
Eliot> and then leave subsequent usage to catch possible type errors; e.g. (false Eliot> xor: #blah) ifTrue: ... will raise a mustBeBoolean error.
What I don't like about this is that the right operand doesn't get a chance to "boolify" itself, or define its own xor logic. The double-dispatch versions were a lot better at that.
On Tue, Mar 24, 2009 at 1:36 PM, Randal L. Schwartz merlyn@stonehenge.comwrote:
"Eliot" == Eliot Miranda eliot.miranda@gmail.com writes:
Eliot> I think just
True> xor: aBoolean Eliot> ^aBoolean not
False> xor: aBoolean Eliot> ^aBoolean
Eliot> and then leave subsequent usage to catch possible type errors; e.g. (false Eliot> xor: #blah) ifTrue: ... will raise a mustBeBoolean error.
What I don't like about this is that the right operand doesn't get a chance to "boolify" itself, or define its own xor logic. The double-dispatch versions were a lot better at that.
If you want to do that you could implement it as
False> xor: aBoolean ^aBoolean not not
but I'd argue that isn't necessary. The old code didn't type check and we've lived with it for a loooong time.
But in any case, the not is a form of double-dispatch. It just points out that one can use not instead of xorTrue and is more comprehensible because "not" is familiar.
-- Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095 merlyn@stonehenge.com URL:http://www.stonehenge.com/merlyn/ Smalltalk/Perl/Unix consulting, Technical writing, Comedy, etc. etc. See http://methodsandmessages.vox.com/ for Smalltalk and Seaside discussion
On Tue, 24 Mar 2009 23:01:45 +0100, Eliot Miranda wrote:
On Tue, Mar 24, 2009 at 1:36 PM, Randal L. Schwartz wrote:
> "Eliot" == Eliot Miranda eliot.miranda@gmail.com writes:
Eliot> I think just
True> xor: aBoolean Eliot> ^aBoolean not
False> xor: aBoolean Eliot> ^aBoolean
Eliot> and then leave subsequent usage to catch possible type errors; e.g. (false Eliot> xor: #blah) ifTrue: ... will raise a mustBeBoolean error.
What I don't like about this is that the right operand doesn't get a chance to "boolify" itself, or define its own xor logic. The double-dispatch versions were a lot better at that.
If you want to do that you could implement it as
False> xor: aBoolean ^aBoolean not not
This is, by Randal E. Bryant (who's using Shannon's expansion), equivalent to
^ aBoolean ifTrue: [true] ifFalse: [false]
which the Squeak inlining compiler's magic + decompiler transforms to
^ aBoolean and: [true]
When implemented in one of these two forms, a comment can explain that it's a not not implementation.
but I'd argue that isn't necessary. The old code didn't type check and we've lived with it for a loooong time.
I think that Randal makes the point; especially when the result is stored for later. The other boolean messages do implicit (by the inlining compiler) check their argument for #isBoolean, that's what should be done by #xor: as well.
But in any case, the not is a form of double-dispatch. It just points out that one can use not instead of xorTrue and is more comprehensible because "not" is familiar.
-- Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095 merlyn@stonehenge.com URL:http://www.stonehenge.com/merlyn/ Smalltalk/Perl/Unix consulting, Technical writing, Comedy, etc. etc. See http://methodsandmessages.vox.com/ for Smalltalk and Seaside discussion
On Tue, Mar 24, 2009 at 9:27 PM, Klaus D. Witzel klaus.witzel@cobss.comwrote:
On Tue, 24 Mar 2009 23:01:45 +0100, Eliot Miranda wrote:
On Tue, Mar 24, 2009 at 1:36 PM, Randal L. Schwartz wrote:
> "Eliot" == Eliot Miranda eliot.miranda@gmail.com writes:
Eliot> I think just
True> xor: aBoolean Eliot> ^aBoolean not
False> xor: aBoolean Eliot> ^aBoolean
Eliot> and then leave subsequent usage to catch possible type errors; e.g. (false Eliot> xor: #blah) ifTrue: ... will raise a mustBeBoolean error.
What I don't like about this is that the right operand doesn't get a chance to "boolify" itself, or define its own xor logic. The double-dispatch versions were a lot better at that.
If you want to do that you could implement it as
False> xor: aBoolean ^aBoolean not not
This is, by Randal E. Bryant (who's using Shannon's expansion), equivalent to
^ aBoolean ifTrue: [true] ifFalse: [false]
which the Squeak inlining compiler's magic + decompiler transforms to
^ aBoolean and: [true]
When implemented in one of these two forms, a comment can explain that it's a not not implementation.
but I'd argue that isn't necessary. The old code didn't type check and
we've lived with it for a loooong time.
I think that Randal makes the point; especially when the result is stored for later.
While it might be convenient it isn't strictly necessary. Smalltalk defers type checks until usage. Not checking in False>>xor: would be consistent with this.
The other boolean messages do implicit (by the inlining compiler) check
their argument for #isBoolean, that's what should be done by #xor: as well.
No they do not. Look at | and & :
False>>| aBoolean "Evaluating disjunction (OR) -- answer with the argument, aBoolean."
^aBoolean
True>>&& alternativeObject "Evaluating conjunction -- answer alternativeObject since receiver is true."
^alternativeObject
But in any case, the not is a form of double-dispatch. It just points out
that one can use not instead of xorTrue and is more comprehensible because "not" is familiar.
-- Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095 merlyn@stonehenge.com URL:http://www.stonehenge.com/merlyn/ Smalltalk/Perl/Unix consulting, Technical writing, Comedy, etc. etc. See http://methodsandmessages.vox.com/ for Smalltalk and Seaside discussion
-- "If at first, the idea is not absurd, then there is no hope for it". Albert Einstein
On Thu, 26 Mar 2009 17:21:08 +0100, Eliot Miranda wrote:
On Tue, Mar 24, 2009 at 9:27 PM, Klaus D. Witzel wrote:
On Tue, 24 Mar 2009 23:01:45 +0100, Eliot Miranda wrote:
On Tue, Mar 24, 2009 at 1:36 PM, Randal L. Schwartz wrote:
>> "Eliot" == Eliot Miranda eliot.miranda@gmail.com writes:
Eliot> I think just
True> xor: aBoolean Eliot> ^aBoolean not
False> xor: aBoolean Eliot> ^aBoolean
Eliot> and then leave subsequent usage to catch possible type errors; e.g. (false Eliot> xor: #blah) ifTrue: ... will raise a mustBeBoolean error.
What I don't like about this is that the right operand doesn't get a chance to "boolify" itself, or define its own xor logic. The double-dispatch versions were a lot better at that.
If you want to do that you could implement it as
False> xor: aBoolean ^aBoolean not not
This is, by Randal E. Bryant (who's using Shannon's expansion), equivalent to
^ aBoolean ifTrue: [true] ifFalse: [false]
which the Squeak inlining compiler's magic + decompiler transforms to
^ aBoolean and: [true]
When implemented in one of these two forms, a comment can explain that it's a not not implementation.
but I'd argue that isn't necessary. The old code didn't type check and
we've lived with it for a loooong time.
I think that Randal makes the point; especially when the result is stored for later.
While it might be convenient it isn't strictly necessary.
Right. I was coming from here: given z the result and p,q operands for #xor:, then
z := p xor: q => z := p ifTrue: [q not] ifFalse: [q] => that is, q must be evaluated in both cases. This is how I would inline #xor:, by sending the single #not conditionally.
Smalltalk defers type checks until usage. Not checking in False>>xor: would be consistent with this.
Sure. If people do like conditional evaluation of #xor:'s argument then let 'em have it :)
The other boolean messages do implicit (by the inlining compiler) check
their argument for #isBoolean, that's what should be done by #xor: as well.
No they do not. Look at | and & :
False>>| aBoolean "Evaluating disjunction (OR) -- answer with the argument, aBoolean."
^aBoolean
True>>&& alternativeObject "Evaluating conjunction -- answer alternativeObject since receiver is true."
^alternativeObject
But in any case, the not is a form of double-dispatch. It just points out that one can use not instead of xorTrue and is more comprehensible because "not" is familiar.
NP.
-- Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095 merlyn@stonehenge.com URL:http://www.stonehenge.com/merlyn/ Smalltalk/Perl/Unix consulting, Technical writing, Comedy, etc. etc. See http://methodsandmessages.vox.com/ for Smalltalk and Seaside discussion
-- "If at first, the idea is not absurd, then there is no hope for it". Albert Einstein
Eliot Miranda wrote:
I think just
True>>xor: aBoolean ^aBoolean not
False>>xor: aBoolean ^aBoolean
<OT> One of my first excerices in Smalltalk was to implement an exclusive or as "||", without being told that xor: is exactly that. The reference implementation was the above, if memory serves me right. </OT>
Sorry for reminiscing in public...
Hi, Keith, Boolean>>xor: requires a Boolean as a parameter, not a BlockContext. See the definition of xor:.
Kazuhiro Abe
2009/3/24 Keith Hodges keith_hodges@yahoo.co.uk:
true xor: [ true ] => true
discuss
Keith
Kazuhiro ABE wrote:
Hi, Keith, Boolean>>xor: requires a Boolean as a parameter, not a BlockContext. See the definition of xor:.
Kazuhiro Abe
2009/3/24 Keith Hodges keith_hodges@yahoo.co.uk:
true xor: [ true ] => true
discuss
Keith
I think that the following would be more consistent.
xor: aBoolean
^(self == aBoolean value) not
I was quite pleased to find an application for xor: my first in 15 years of Smalltalking.
Keith
On 24.03.2009, at 04:10, Keith Hodges wrote:
Kazuhiro ABE wrote:
Hi, Keith, Boolean>>xor: requires a Boolean as a parameter, not a BlockContext. See the definition of xor:.
Kazuhiro Abe
2009/3/24 Keith Hodges keith_hodges@yahoo.co.uk:
true xor: [ true ] => true
discuss
Keith
I think that the following would be more consistent.
xor: aBoolean
^(self == aBoolean value) not
This even looks suspicious. #value is not a Boolean protocol.
I was quite pleased to find an application for xor: my first in 15 years of Smalltalking.
It is rather rarely used indeed. So IMHO adding a guard that makes sure aBoolean is, in fact, a Boolean, would alert the occasional user to the fact that #xor: has no short-circuiting logic. Besides, #xor: is defined in the ANSI standard so we should not water down its meaning willy-nilly, for compatibility with other Smalltalks.
- Bert -
I think the concern of Keith and others who think xor: needs to be changed is that and: and or: take a block as an argument, so it seems natural that xor: would work when you give it a block as an argument. I agree. It seems natural. However, there are good reasons for it to be different. So, it should give a warning when given a block.
-Ralph
squeak-dev@lists.squeakfoundation.org