<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Mar 21, 2018 at 5:15 PM, Levente Uzonyi <span dir="ltr"><<a href="mailto:leves@caesar.elte.hu" target="_blank">leves@caesar.elte.hu</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">On Wed, 21 Mar 2018, Eliot Miranda wrote:<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
<br>
On Wed, Mar 21, 2018 at 2:48 PM, Levente Uzonyi <<a href="mailto:leves@caesar.elte.hu" target="_blank">leves@caesar.elte.hu</a>> wrote:<br>
      On Tue, 20 Mar 2018, Chris Cunningham wrote:<br>
<br>
            Hi.  Reopening this thread - probably tomorrow will implement 'better' solution (with documentation).<br>
<br>
            On Sat, Feb 10, 2018 at 12:03 PM, Tobias Pape <<a href="mailto:Das.Linux@gmx.de" target="_blank">Das.Linux@gmx.de</a>> wrote:<br>
<br>
                  > On 10.02.2018, at 20:36, Tony Garnock-Jones <<a href="mailto:tonyg@leastfixedpoint.com" target="_blank">tonyg@leastfixedpoint.com</a>> wrote:<br>
                  ><br>
                  > On 02/10/2018 07:02 PM, Levente Uzonyi wrote:<br>
                  >> So,<br>
                  >>    a perform: {#or:. #xor:. #and:} atRandom with: b<br>
                  >> would just work for that imaginary interpreter if b were a Boolean.<br>
                  ><br>
                  > Yes, that "interpreter" works just fine today, if b is a Boolean. It's<br>
                  > the case where b is a Boolean-producing expression - such as in a "lazy"<br>
                  > interpreter - that doesn't work without Fabio's proposed change.<br>
                  ><br>
                  > I went and looked at the ANSI standard (draft), btw [1].<br>
                  ><br>
                  > There, #xor: is specified as taking only a boolean.<br>
                  ><br>
                  > So this would be an extension, potentially affecting portability, for<br>
                  > what that's worth these days.<br>
                  ><br>
                  > I think the performance objection has been well-refuted, and I see the<br>
                  > consistency benefit as being real, but probably pretty limited, and I<br>
                  > kind of don't like the potential portability implications.<br>
<br>
                  I presume the main "feeling" here is parallelity:<br>
<br>
                  #& takes an evaluated boolean   #and: takes an unevaluated block<br>
                  #| takes an evaluated boolean   #or: takes an unevaluated block<br>
<br>
                  #xor: takes an evaluated boolean but looks like #and: and #or:,<br>
                  So it seems to belong to the right side, and then we think again about<br>
                  the left side, come up with symbols, only to find that #~= and #~~ are already there.<br>
<br>
                  So, just lets go all the way and document #xor: better, not making take it a block,<br>
                  maybe pointing out that #~= ist typically better fitted…<br>
<br>
                  Best regards<br>
                          -Tobias<br>
<br>
<br>
            So, I have written some tests for speed and 'ensuring the arguments are booleans', with another proposed solution.<br>
<br>
            First, speed:<br>
<br>
            #xor: base<br>
            #~= is 124% slower (or 2-1/4 as much time as existing xor: method)<br>
            #~~ is 75% faster<br>
            #cbcXor: is 32% slower<br>
<br>
            Note: for real speed, use ~~ , not ~= !<br>
<br>
            Why cbcXor: ?  It is the only one that makes sure the arguments are boolean - fails otherwise.<br>
<br>
<br>
Here is a simpler and faster alternative:<br>
<br>
True >> #xor: aBoolean<br>
<br>
        aBoolean ifTrue: [ ^false ] ifFalse: [ ^true ]<br>
<br>
False >> #xor: aBoolean<br>
<br>
        aBoolean ifTrue: [ ^true ] ifFalse: [ ^false ]<br>
<br>
<br>
and is this noticeably slower?<br>
<br>
 True >> #xor: aBoolean<br>
<br>
        ^aBoolean ifTrue: [ false ] ifFalse: [ true ]<br>
<br>
False >> #xor: aBoolean<br>
<br>
        ^aBoolean ifTrue: [ true ] ifFalse: [ false ]<br>
</blockquote>
<br></div></div>
Yes, it is. Here are the bytecodes for your suggestion:<br>
<br>
33 <10> pushTemp: 0<br>
34 <99> jumpFalse: 37<br>
35 <71> pushConstant: true<br>
36 <90> jumpTo: 38<br>
37 <72> pushConstant: false<br>
38 <7C> returnTop<br>
<br>
And for my variant:<br>
<br>
33 <10> pushTemp: 0<br>
34 <98> jumpFalse: 36<br>
35 <79> return: true<br>
36 <7A> return: false<br>
<br>
I measured the latter to be 14% faster.</blockquote><div><br></div><div>For xor: it's hardly worth it.  Nicer if the compiler and decompiler did the transformation...</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="HOEnZb"><font color="#888888"><br>
<br>
Levente</font></span><div class="HOEnZb"><div class="h5"><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
but I would much prefer to see either<br>
<br>
Boolean>>xor: aBooleanOrBlock<br>
<br>
    ^ aBooleanOrBlock value not<br>
<br>
or<br>
<br>
True >> #xor: aBooleanOrBlock<br>
<br>
        ^aBooleanOrBlock value ifTrue: [ false ] ifFalse: [ true ]<br>
<br>
False >> #xor: aBooleanOrBlock<br>
<br>
        ^aBooleanOrBlock value ifTrue: [ true ] ifFalse: [ false ]<br>
<br>
The lack of symmetry with and: and or: is, IMO, bad.<br>
<br>
<br>
      Levente<br>
<br>
<br>
            Tests to run:<br>
<br>
            First, install<br>
<br>
            True>>cbcXor: boolean<br>
            ^boolean isFalse<br>
            True>>isTrue<br>
            ^true<br>
            True>>isFalse<br>
            ^false<br>
            False>>cbcXor: boolean<br>
            ^boolean isTrue<br>
            False>>isFalse<br>
            ^true<br>
            False>>isTrue<br>
            ^false<br>
<br>
            "Setup"<br>
            pairs := #( true false true true false false false true ).<br>
            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. }.<br>
            methods := {<br>
            [:f :s| ]. <br>
            [:f :s| f xor: s]. <br>
            [:f :s| f cbcXor: s]. <br>
            [:f :s| f ~= s]. <br>
            [:f :s| f ~~ s].<br>
            }.<br>
            "Validity Test"<br>
            validCheck := methods collect: [:m|<br>
            { <br>
            m sourceString. <br>
            #( true false false true ) = (pairs pairsCollect: [:a :b| [m value: a value: b] on: Error do: [#error]])<br>
            ifTrue: ['Valid'] ifFalse: ['ERRORS'].<br>
            pairs pairsCollect: [:a :b| [m value: a value: b] on: Error do: [#error]]. <br>
            }].<br>
            "all methods are valid"<br>
            "Testing that non-booleans actually result in errors, and not false positive/negatives"<br>
            invalidCheck := methods collect: [:m|<br>
            { <br>
            m sourceString. <br>
            ((invalidPairs pairsCollect: [:a :b| [m value: a value: b] on: Error do: [#error]]) select: [:r| r = #error]) size = 8<br>
            ifTrue: ['Valid'] ifFalse: ['ERRORS'].<br>
            invalidPairs pairsCollect: [:a :b| [m value: a value: b] on: Error do: [#error]]. <br>
            }].<br>
            "Only #cbcXor: correctly fails all of these.  Some interesting results..."<br>
            "Timing test.  Need to run 10,000,000 to get reasonable distinctions on my machine."<br>
            timing := methods collect: [:m|<br>
            { m sourceString.  [[10000000 timesRepeat: [pairs pairsDo: m]] timeToRun] on: Error do: [#invalid]. }<br>
            ].<br>
            "And showing percentage slower"<br>
            base := timing first second.<br>
            bench := timing second second - base.<br>
            timing allButFirst collect: [:res| { res first. this := res second - base. ((this - bench) * 100 / bench) rounded. }].<br>
<br>
            Thanks,<br>
            cbc<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
--<br>
_,,,^..^,,,_<br>
best, Eliot<br>
<br>
</blockquote>
</div></div><br><br>
<br></blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"><div><span style="font-size:small;border-collapse:separate"><div>_,,,^..^,,,_<br></div><div>best, Eliot</div></span></div></div></div>
</div></div>