<br><br><div class="gmail_quote">On Tue, Nov 2, 2010 at 1:50 PM, Juan Vuletich <span dir="ltr">&lt;<a href="mailto:juan@jvuletich.org">juan@jvuletich.org</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
Eliot Miranda wrote:<div><div></div><div class="h5"><br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
<br>
On Tue, Nov 2, 2010 at 1:23 PM, Juan Vuletich &lt;<a href="mailto:juan@jvuletich.org" target="_blank">juan@jvuletich.org</a> &lt;mailto:<a href="mailto:juan@jvuletich.org" target="_blank">juan@jvuletich.org</a>&gt;&gt; wrote:<br>

<br>
    Nicolas Cellier wrote:<br>
<br>
<br>
        I&#39;d say which selector are implemented in Pharo and Cuis ?<br>
        We should better converge.<br>
<br>
        Nicolas<br>
         <br>
<br>
    Hi folks,<br>
<br>
    Cuis doesn&#39;t include any of them yet. I can add whatever people<br>
    prefer. What I&#39;d do different is the implementation:<br>
<br>
    fold: aBinaryBlock<br>
<br>
      &quot;Evaluate the block with the first two elements of the receiver,<br>
       then with the result of the first evaluation and the next element,<br>
       and so on.  Answer the result of the final evaluation. If the<br>
    receiver<br>
       is empty, raise an error. If the receiver has a single element,<br>
    answer<br>
       that element.&quot;<br>
      &quot;<br>
      #(&#39;if&#39; &#39;it&#39; &#39;is&#39; &#39;to&#39; &#39;be&#39; &#39;it&#39; &#39;is&#39; &#39;up&#39; &#39;to&#39; &#39;me&#39;) fold: [:a<br>
    :b | a, &#39; &#39;, b]<br>
      &quot;<br>
      | noPreviousValue |<br>
      noPreviousValue := Object new.    &quot;something that can&#39;t be in<br>
    the receiver&quot;<br>
      ^self inject: noPreviousValue into: [ :previousValue :each |<br>
          previousValue == noPreviousValue<br>
              ifTrue: [ each ]<br>
              ifFalse: [ aBinaryBlock value: previousValue value: each ]]<br>
<br>
    This is easier to understand, and it also makes clear the relation<br>
    between #fold: (or #reduce:) and #inject:into: .<br>
<br>
<br>
I disagree.   inject:into: is not particularly easy to understand, whereas both the existing fold: and reduce: are understandable in terms of do:.<br>
</blockquote>
<br></div></div>
I say this is easier to understand, given that #inject:into: is already understood. #inject:into: and #fold: / #reduce: are very close in what they do. So close, that it is best to show how they differ. That&#39;s what my implementation does. Showing the use of #inject:into:  (with proper names for block args) is a didactic bonus.<div class="im">
<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Also the use of inject:into: isn&#39;t really buying you anything since the logic in the block within the inject:into: usage is as complex as that within fold: or reduce:. Further, this /is/ a lot slower because of the extra level of evaluation (there&#39;s an extra block activation around each element).</blockquote>
</div></blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><div class="im"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

 <br>
best,<br>
Eliot<br>
</blockquote>
<br></div>
No, it is not slower:<br>
   [100000 timesRepeat: [#(&#39;if&#39; &#39;it&#39; &#39;is&#39; &#39;to&#39; &#39;be&#39; &#39;it&#39; &#39;is&#39; &#39;up&#39; &#39;to&#39; &#39;me&#39;) fold: [:a :b | a, &#39; &#39;, b]]] timeToRun 2710 | 879<br>
   [100000 timesRepeat: [#(&#39;if&#39; &#39;it&#39; &#39;is&#39; &#39;to&#39; &#39;be&#39; &#39;it&#39; &#39;is&#39; &#39;up&#39; &#39;to&#39; &#39;me&#39;) foldx: [:a :b | a, &#39; &#39;, b]]] timeToRun 2723 | 874<br>
   [100000 timesRepeat: [#(&#39;if&#39; &#39;it&#39; &#39;is&#39; &#39;to&#39; &#39;be&#39; &#39;it&#39; &#39;is&#39; &#39;up&#39; &#39;to&#39; &#39;me&#39;) reduce: [:a :b | a, &#39; &#39;, b]]] timeToRun 2780 | 881<br>
</blockquote><div><br></div><div>Be very careful to run these under the same conditions.  You&#39;d need to run each of these immediately following a GC to get meaningful results.  Also use 1 to: n do for the outer loop since timesRepeat: uses do: and so the measurement harness is probably a significant fraction of the run-time.  Also measure the single-element cost.  BTW, I would use (1 to: 10) fold: [:a :b| a + b] to reduce the overhead of string concatenation &amp; allocation and focus more on the costs of the various fold: implementations.</div>
<div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<br>
#foldx: is my implementation. In all cases, the first number is regular interpreter Squeak 4.2.4beta1U.app, the second number is Cog Squeak 5.8b10-1.app on a 1.6GHz Mac mini.<br>
<br>
The argument about complexity is more aesthetic than anything.</blockquote><div><br></div><div>Indeed; and so a matter of taste.  My aesthetics end up preferring fold: over the inject:into: based one :/</div><div><br></div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">My version doesn&#39;t need assignment to outer temps, and I see that &#39;cleaner&#39; and closer to FP.<br>
</blockquote><div><br></div><div><div><br></div><div>But the assignment to the outer temp is hidden in inject:into:; it&#39;s still there ;)</div></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">

<br>
Cheers,<br><font color="#888888">
Juan Vuletich<br>
<br>
<br>
</font></blockquote></div><br>