true xor: [ true ] => true
discuss Keith |
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 <[hidden email]> wrote: Keith Hodges wrote: 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. -- http://gulik.pbwiki.com/ |
In reply to this post by keith1y
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 |
In reply to this post by keith1y
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 <[hidden email]>: > 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 <[hidden email]>: > >> true xor: [ true ] => true >> >> discuss >> >> Keith 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 <[hidden email]>: >> >>> 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 |
In reply to this post by Nicolas Cellier
Nicolas Cellier 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... > True! > 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 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 |
In reply to this post by Nicolas Cellier
On Mon, Mar 23, 2009 at 6:32 PM, Nicolas Cellier <[hidden email]> wrote: 1) #xor: should not take a block as argument. 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 +1
|
Eliot Miranda wrote:
> > > On Mon, Mar 23, 2009 at 6:32 PM, Nicolas Cellier > <[hidden email] > <mailto:[hidden email]>> 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 |
In reply to this post by Eliot Miranda-2
On 24.03.2009, at 17:59, Eliot Miranda wrote:
- Bert - |
In reply to this post by Eliot Miranda-2
>>>>> "Eliot" == Eliot Miranda <[hidden email]> 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. -- Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095 <[hidden email]> <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 1:36 PM, Randal L. Schwartz <[hidden email]> wrote: >>>>> "Eliot" == Eliot Miranda <[hidden email]> writes: 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.
|
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 <[hidden email]> 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 >> <[hidden email]> <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 Tue, Mar 24, 2009 at 9:27 PM, Klaus D. Witzel <[hidden email]> wrote: On Tue, 24 Mar 2009 23:01:45 +0100, Eliot Miranda wrote: 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
|
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 <[hidden email]> 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 >>>> <[hidden email]> <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 >> |
In reply to this post by Eliot Miranda-2
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... |
Free forum by Nabble | Edit this page |