[squeak-dev] The Inbox: Kernel-fn.1151.mcz

Eliot Miranda eliot.miranda at gmail.com
Wed Mar 21 23:09:59 UTC 2018


On Wed, Mar 21, 2018 at 2:48 PM, Levente Uzonyi <leves at caesar.elte.hu>
wrote:

> On Tue, 20 Mar 2018, Chris Cunningham wrote:
>
> Hi.  Reopening this thread - probably tomorrow will implement 'better'
>> solution (with documentation).
>>
>> On Sat, Feb 10, 2018 at 12:03 PM, Tobias Pape <Das.Linux at gmx.de> wrote:
>>
>>       > On 10.02.2018, at 20:36, Tony Garnock-Jones <
>> tonyg at leastfixedpoint.com> wrote:
>>       >
>>       > On 02/10/2018 07:02 PM, Levente Uzonyi wrote:
>>       >> So,
>>       >>    a perform: {#or:. #xor:. #and:} atRandom with: b
>>       >> would just work for that imaginary interpreter if b were a
>> Boolean.
>>       >
>>       > Yes, that "interpreter" works just fine today, if b is a Boolean.
>> It's
>>       > the case where b is a Boolean-producing expression - such as in a
>> "lazy"
>>       > interpreter - that doesn't work without Fabio's proposed change.
>>       >
>>       > I went and looked at the ANSI standard (draft), btw [1].
>>       >
>>       > There, #xor: is specified as taking only a boolean.
>>       >
>>       > So this would be an extension, potentially affecting portability,
>> for
>>       > what that's worth these days.
>>       >
>>       > I think the performance objection has been well-refuted, and I
>> see the
>>       > consistency benefit as being real, but probably pretty limited,
>> and I
>>       > kind of don't like the potential portability implications.
>>
>>       I presume the main "feeling" here is parallelity:
>>
>>       #& takes an evaluated boolean   #and: takes an unevaluated block
>>       #| takes an evaluated boolean   #or: takes an unevaluated block
>>
>>       #xor: takes an evaluated boolean but looks like #and: and #or:,
>>       So it seems to belong to the right side, and then we think again
>> about
>>       the left side, come up with symbols, only to find that #~= and #~~
>> are already there.
>>
>>       So, just lets go all the way and document #xor: better, not making
>> take it a block,
>>       maybe pointing out that #~= ist typically better fitted…
>>
>>       Best regards
>>               -Tobias
>>
>>
>> So, I have written some tests for speed and 'ensuring the arguments are
>> booleans', with another proposed solution.
>>
>> First, speed:
>>
>> #xor: base
>> #~= is 124% slower (or 2-1/4 as much time as existing xor: method)
>> #~~ is 75% faster
>> #cbcXor: is 32% slower
>>
>> Note: for real speed, use ~~ , not ~= !
>>
>> Why cbcXor: ?  It is the only one that makes sure the arguments are
>> boolean - fails otherwise.
>>
>
> Here is a simpler and faster alternative:
>
> True >> #xor: aBoolean
>
>         aBoolean ifTrue: [ ^false ] ifFalse: [ ^true ]
>
> False >> #xor: aBoolean
>
>         aBoolean ifTrue: [ ^true ] ifFalse: [ ^false ]


and is this noticeably slower?

 True >> #xor: aBoolean

        ^aBoolean ifTrue: [ false ] ifFalse: [ true ]

False >> #xor: aBoolean

        ^aBoolean ifTrue: [ true ] ifFalse: [ false ]

but I would much prefer to see either

Boolean>>xor: aBooleanOrBlock

    ^ aBooleanOrBlock value not

or

True >> #xor: aBooleanOrBlock

        ^aBooleanOrBlock value ifTrue: [ false ] ifFalse: [ true ]

False >> #xor: aBooleanOrBlock

        ^aBooleanOrBlock value ifTrue: [ true ] ifFalse: [ false ]

The lack of symmetry with and: and or: is, IMO, bad.


Levente
>
>
>
>> Tests to run:
>>
>> First, install
>>
>> True>>cbcXor: boolean
>> ^boolean isFalse
>> True>>isTrue
>> ^true
>> True>>isFalse
>> ^false
>> False>>cbcXor: boolean
>> ^boolean isTrue
>> False>>isFalse
>> ^true
>> False>>isTrue
>> ^false
>>
>> "Setup"
>> pairs := #( true false true true false false false true ).
>> invalidPairs := { true. 1. true. #[ 1 3 0 9 ]. true. 'abc'. false. 1.
>> false. #[ 1 3 0 9 ]. false. 'abc'. 'abc'. true. #[ 1 3 0 9 ]. false. }.
>> methods := {
>> [:f :s| ].
>> [:f :s| f xor: s].
>> [:f :s| f cbcXor: s].
>> [:f :s| f ~= s].
>> [:f :s| f ~~ s].
>> }.
>> "Validity Test"
>> validCheck := methods collect: [:m|
>> {
>> m sourceString.
>> #( true false false true ) = (pairs pairsCollect: [:a :b| [m value: a
>> value: b] on: Error do: [#error]])
>> ifTrue: ['Valid'] ifFalse: ['ERRORS'].
>> pairs pairsCollect: [:a :b| [m value: a value: b] on: Error do:
>> [#error]].
>> }].
>> "all methods are valid"
>> "Testing that non-booleans actually result in errors, and not false
>> positive/negatives"
>> invalidCheck := methods collect: [:m|
>> {
>> m sourceString.
>> ((invalidPairs pairsCollect: [:a :b| [m value: a value: b] on: Error do:
>> [#error]]) select: [:r| r = #error]) size = 8
>> ifTrue: ['Valid'] ifFalse: ['ERRORS'].
>> invalidPairs pairsCollect: [:a :b| [m value: a value: b] on: Error do:
>> [#error]].
>> }].
>> "Only #cbcXor: correctly fails all of these.  Some interesting results..."
>> "Timing test.  Need to run 10,000,000 to get reasonable distinctions on
>> my machine."
>> timing := methods collect: [:m|
>> { m sourceString.  [[10000000 timesRepeat: [pairs pairsDo: m]] timeToRun]
>> on: Error do: [#invalid]. }
>> ].
>> "And showing percentage slower"
>> base := timing first second.
>> bench := timing second second - base.
>> timing allButFirst collect: [:res| { res first. this := res second -
>> base. ((this - bench) * 100 / bench) rounded. }].
>>
>> Thanks,
>> cbc
>>
>>
>
>
>


-- 
_,,,^..^,,,_
best, Eliot
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20180321/61898b16/attachment.html>


More information about the Squeak-dev mailing list