<html><head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
  </head>
  <body>
    <p>One more update. Demonstrating multi return value handling, multi
      return handler sending, and promise pipelining. Here is a new
      version <68> of PromisesLocal, attached. I cleaned up
      #<<*.<br/>
    </p>
    <p>For exploring in Squeak, as Cuis is breaking on #becomeForward:,
      doIt the following and goto the RefsTest.</p>
    <blockquote>
      <p>Installer ss project: 'Cryptography'; install: 'PromisesLocal'.</p>
    </blockquote>
    <p> I added a promise chaining test, such that another handler is
      sent to the resulting promise of the second union handler,
      accepting all three return objects. This union 2 handler returns
      g, which the chain handler expects. So here is promise pipelining,
      where messages sent to a promise have a message sent to it. So
      this is 6 promises.</p>
    <blockquote>
      <p>RefsTest>>#testMultiReturnsFromNearPromiseWithPromiseChaining<br/>
        <br/>
            | selectCount pair promise chainFlag promiseChain union1Flag
        union2Flag |<br/>
            union1Flag := false.<br/>
            union2Flag := false.<br/>
            chainFlag := false.<br/>
            selectCount := 0.<br/>
            promise := (pair := self promiseResolverPair) key xgcd: 9.<br/>
            promise <<* [:each | selectCount := selectCount + 1.
        Transcript cr; show: 'each = ', each].<br/>
            promise <<* [:g :s :t | union1Flag := true. Transcript
        cr; show: 'Union 1: g = ', g, '; s = ', s, '; t = ', t. g].<br/>
            promiseChain := promise <<* [:g :s :t | union2Flag :=
        true. Transcript cr; show: 'Union 2: g = ', g, '; s = ', s, '; t
        = ', t. g].<br/>
            promiseChain <<* [:g | chainFlag := true. Transcript
        cr; show: 'Chain of Union 2: g = ', g. g].<br/>
            pair value resolve: 21.<br/>
            (Delay forMilliseconds: 333) wait.<br/>
            self assert: (selectCount == 3).<br/>
            self assert: (union1Flag).<br/>
            self assert: (union2Flag).<br/>
            self assert: (chainFlag).<br/>
      </p>
    </blockquote>
    <p>Here is the Transcript output:</p>
    <blockquote>
      <p>each = 3<br/>
        each = 7<br/>
        each = 3<br/>
        Union 1: g = 3; s = 7; t = 3<br/>
        Union 2: g = 3; s = 7; t = 3<br/>
        Chain of Union 2: g = 3<br/>
      </p>
    </blockquote>
    <pre class="moz-signature" cols="72">-- 
❤️‍🔥🐰</pre>
    <p></p>
    <div class="moz-cite-prefix">On 6/24/23 10:30, rabbit via Cuis-dev
      wrote:<br/>
    </div>
    <blockquote type="cite" cite="mid:488f0eb2-cd0d-49e9-2440-4cd36b0055a1@callistohouse.org">
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
      <p>My apologies for the undue traffic. I feel the need to clarify
        what is happening. The promise local is set to the result of the
        eventual send of #xgcd: to the promise of the initial pair. So
        we have 2 promises. When the resolver of the initial pair is
        resolved, it resolves the initial pair promise, which sends the
        #xgcd: message and thus resolves the 2nd promise to cause the
        multiResponseHanldlers to be sent in turn. Each send of
        #<<* also returns a promise, so we actually have 3
        momentarily, 3 times, each before the 3rd gets GCed. Before the
        4th & 5th? I dunno. Perhaps we have 5 Promises momentarily.</p>
      <p>rabbit<br/>
      </p>
      <div class="moz-cite-prefix">On 6/24/23 10:18, rabbit via Cuis-dev
        wrote:<br/>
      </div>
      <blockquote type="cite" cite="mid:2ca1874e-0390-997e-8196-872724ab8906@callistohouse.org">
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
        <p>I forgot to mention, to resolve the promise <pair value
          resolve: 21>.</p>
        <p>But I'm getting this #becomeForward: error on promise
          resolution, in Cuis. It's a temporary issue.<br/>
        </p>
        <blockquote>
          <p>promise := ((pair := self promiseResolverPair) key xgcd:
            9).</p>
          <p>promise <<* [:each | selectCount := selectCount + 1.
            Transcript cr; show: 'each = ', each];<br/>
            promise <<* [:g :s :t | firstUnionFlag := true.
            Transcript cr; show: 'gcd = 'g'].<br/>
            promise <<* [:g :s :t | secondUnionFlag := true.
            Transcript cr; show: 'g = ', g, '; s = ', s, '; t = ', t.].</p>
          <p>pair value resolve: 21.<br/>
            <br/>
          </p>
        </blockquote>
        <div class="moz-cite-prefix">On 6/24/23 10:03, rabbit via
          Cuis-dev wrote:<br/>
        </div>
        <blockquote type="cite" cite="mid:620df98c-3dfd-fdd6-7c58-79bc8629e3a3@callistohouse.org">
          <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
          <p>Hi.</p>
          <p>An interesting facet of eventual sending with promises is
            the bonus of sending multiple result handlers to a single
            eventual send result promise. So multiple result handlers,
            or whatever best describes, for whatever that is worth.</p>
          <p>Here are 3 return handlers, <br/>
          </p>
          <blockquote>
            <p>promise := ((pair := self promiseResolverPair) key xgcd:
              9).</p>
          </blockquote>
          <p>the first for each argument <br/>
          </p>
          <blockquote>
            <p>promise <<* [:each | selectCount := selectCount +
              1. Transcript cr; show: 'each = ', each];</p>
          </blockquote>
          <p>and the last 2 for all three arguments.</p>
          <blockquote>
            <p>promise <<* [:g :s :t | firstUnionFlag := true.
              Transcript cr; show: 'gcd = 'g'].</p>
            <p>promise <<* [:g :s :t | secondUnionFlag := true.
              Transcript cr; show: 'g = ', g, '; s = ', s, '; t = ',
              t.].</p>
          </blockquote>
          <pre class="moz-signature" cols="72">--
❤️‍🔥🐰



</pre>
          <div class="moz-cite-prefix">On 6/23/23 16:15, Luciano
            Notarfrancesco wrote:<br/>
          </div>
          <blockquote type="cite" cite="mid:CAL5GDyoz_kWja=LN_ods3VxmbsnAAqt9OgP0_AL8bXgpgbYC6A@mail.gmail.com">
            <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
            <div dir="auto">Right, good point! Fortunately, messages
              with multiple return values are not very common in my
              system, I just have a few examples, and I’ll rewrite them
              with Juan’s suggestion, and I’ll keep your point in mind.</div>
            <div><br/>
              <div class="gmail_quote">
                <div dir="ltr" class="gmail_attr">On Fri, 23 Jun 2023 at
                  21:33 Nicolas Cellier <<a href="mailto:nicolas.cellier.aka.nice@gmail.com" moz-do-not-send="true" class="moz-txt-link-freetext">nicolas.cellier.aka.nice@gmail.com</a>>
                  wrote:<br/>
                </div>
                <blockquote class="gmail_quote" style="margin:0px 0px
                  0px
0.8ex;border-left-width:1px;border-left-style:solid;padding-left:1ex;border-left-color:rgb(204,204,204)">
                  <div dir="ltr">
                    <div>Hi all,</div>
                    <div>please note that the keyword message did
                      eliminate the positional semantics found in almost
                      every other language.</div>
                    <div>With multiple return arguments, as well as
                      multiple arguments block workaround, we are back
                      to a kind of positional semantic.</div>
                    <div>Of course, there is still some name used as
                      block args [:g :s :t | ...] but nothing would tell
                      that [:t :g :s | ...] is a mistake.</div>
                    <div>A hint on order can be given by the keyword
                      used to pass block argument, like qr: [:quo :rem |
                      ] or whatever, but when there is more than 2,
                      naming is getting difficult.</div>
                  </div>
                  <div dir="ltr">
                    <div>Nicolas<br/>
                    </div>
                    <div><br/>
                    </div>
                  </div>
                  <br/>
                  <div class="gmail_quote">
                    <div dir="ltr" class="gmail_attr">Le ven. 23 juin
                      2023 à 21:00, rabbit via Cuis-dev <<a href="mailto:cuis-dev@lists.cuis.st" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">cuis-dev@lists.cuis.st</a>>
                      a écrit :<br/>
                    </div>
                    <blockquote class="gmail_quote" style="margin:0px
                      0px 0px
0.8ex;border-left-width:1px;border-left-style:solid;padding-left:1ex;border-left-color:rgb(204,204,204)">
                      <div>
                        <p>I just realized I have been working in
                          squeak. I updated PromisesLocal-rabbt.66.mcz
                          and am attaching it. I am getting the error
                          below when I 'browse code' or 'install
                          Mionticello package'. I do not know. How can I
                          load Monticello packages? Any way to get the
                          Installer available in cuis? Install
                          Monticello config maps?<br/>
                        </p>
                        <p>I appreciate you,<br/>
                          rabbit</p>
                        <p><img src="cid:part1.5AT0viR0.l1CHXOXr@callistohouse.org" alt="" style="width:1180px;max-width:100%" class=""/></p>
                        <p><br/>
                        </p>
                        <div>On 6/22/23 16:21, rabbit via Cuis-dev
                          wrote:<br/>
                        </div>
                        <blockquote type="cite">
                          <p>Hey! I got inspired by your proposal,
                            Luciano, and here's my solution in eventual
                            promises. Code can be loaded as:</p>
                          <blockquote>
                            <p>Installer ss project: 'Cryptography';
                              install: 'ProCrypto.release.3'.<br/>
                            </p>
                          </blockquote>
                          <p>I added a test method <br/>
                          </p>
                          <blockquote>
                            <p>RefsTest>>#testMultiReturns<br/>
                              <br/>
                                  | selectCount unionFlag pair |<br/>
                                  unionFlag := false.<br/>
                                  selectCount := 0.<br/>
                                  ((pair := self promiseResolverPair)
                              key xgcd: 9) <br/>
                                      <<* [:each | selectCount :=
                              selectCount + 1. Transcript cr; show:
                              'each = ', each];<br/>
                                      <<* [:g :s :t | unionFlag :=
                              true. Transcript cr; show: 'g = ', g, '; s
                              = ', s, '; t = ', t. g + s + t].<br/>
                                  pair value resolve: 21.<br/>
                                  (Delay forMilliseconds: 333) wait.<br/>
                                  self assert: (selectCount == 3).<br/>
                                  self assert: (unionFlag).</p>
                          </blockquote>
                          <p>This calls new multireturn #xgcd: method</p>
                          <blockquote>
                            <p>xgcd: anInteger<br/>
                                  " 21 xgcd: 9"<br/>
                                  | g s t |<br/>
                                  g := self gcd: anInteger.<br/>
                                  s := self / g.<br/>
                                  t := anInteger / g.<br/>
                                  ^ { g. s. t}<br/>
                            </p>
                          </blockquote>
                          <p>And in the test method there are eventual
                            sends (#<<*) to the promise of the
                            #xgcd: send once the reciever promise is
                            resolved to 21. This implementation detects
                            cardinality of the continuation block and
                            sends #whenResolved: appropriately, for
                            future evaluation.</p>
                          <blockquote>
                            <p>Object>>#<<* continuation<br/>
                              <br/>
                                  (continuation numArgs == 1)<br/>
                                      ifTrue: [^ self whenResolved:
                              [:result | result do: [:each |
                              continuation value: each]]].<br/>
                                  ^ self whenResolved: [:result |
                              continuation valueWithArguments: result].</p>
                          </blockquote>
                          <p>One can see a 1 cardinality schedules the
                            continuation to evaluate with each result,
                            while a continuation with cardinality 2 or
                            more will be scheduled to receive all
                            results. #valueWithArguments:</p>
                          <p>Here are 2 return handlers, <br/>
                          </p>
                          <blockquote>
                            <p>promise := ((pair := self
                              promiseResolverPair) key xgcd: 9).</p>
                          </blockquote>
                          <p>the first for each argument <br/>
                          </p>
                          <blockquote>
                            <p>promise <<* [:each | selectCount :=
                              selectCount + 1. Transcript cr; show:
                              'each = ', each];</p>
                          </blockquote>
                          <p>and the second for all three arguments.</p>
                          <blockquote>
                            <p>promise <<* [:g :s :t | unionFlag
                              := true. Transcript cr; show: 'g = ', g,
                              '; s = ', s, '; t = ', t. g + s + t].</p>
                          </blockquote>
                          <pre cols="72" style="font-family:monospace">--
❤️‍🔥🐰



</pre>
                          <div>On 6/21/23 09:44, Luciano Notarfrancesco
                            via Cuis-dev wrote:<br/>
                          </div>
                          <blockquote type="cite">
                            <div dir="auto">Interesting, thanks for
                              sharing!</div>
                            <div dir="auto">Actually I think it’s the
                              same thing I did, my implementation calls
BlockClosure>>#valueWithPossibleArgs: and takes only as many
                              arguments as needed by the block but the
                              array can be bigger than that (it should
                              be named #valueWithPossibleArguments: tho,
                              abbreviations are ugly).</div>
                            <div dir="auto"><br/>
                            </div>
                            <div><br/>
                              <div class="gmail_quote">
                                <div dir="ltr" class="gmail_attr">On
                                  Wed, 21 Jun 2023 at 15:37 Christian
                                  Haider via Cuis-dev <<a href="mailto:cuis-dev@lists.cuis.st" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">cuis-dev@lists.cuis.st</a>>
                                  wrote:<br/>
                                </div>
                                <blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left-width:1px;border-left-style:solid;padding-left:1ex;border-left-color:rgb(204,204,204)">
                                  <div lang="DE">
                                    <div>
                                      <p class="MsoNormal"><span lang="EN-CA">I added something
                                          similar to my Values package
                                          (VW and ports).</span></p>
                                      <p class="MsoNormal"><span lang="EN-CA">The source is</span></p>
                                      <p class="MsoNormal" style="margin-left:35.4pt"><span style="font-family:"Courier New"" lang="EN-CA">SequenceableCollection>>asArgumentsIn:
                                          aBlock</span></p>
                                      <p class="MsoNormal" style="margin-left:35.4pt"><span style="font-family:"Courier New"" lang="EN-CA">     "Evaluate
                                          aBlock with the receiver's
                                          elements as parameters.</span></p>
                                      <p class="MsoNormal" style="margin-left:35.4pt"><span style="font-family:"Courier New"" lang="EN-CA">     aBlock
                                          takes its arguments from the
                                          receiver.</span></p>
                                      <p class="MsoNormal" style="margin-left:35.4pt"><span style="font-family:"Courier New"" lang="EN-CA">     'ok'</span></p>
                                      <p class="MsoNormal" style="margin-left:35.4pt"><span style="font-family:"Courier New"" lang="EN-CA">     #(1 2 3)
                                          asArgumentsIn: [:a :b :c | a +
                                          b + c]</span></p>
                                      <p class="MsoNormal" style="margin-left:35.4pt"><span style="font-family:"Courier New"" lang="EN-CA">     #(1 2 3)
                                          asArgumentsIn: [:a :b | a + b]</span></p>
                                      <p class="MsoNormal" style="margin-left:35.4pt"><span style="font-family:"Courier New"" lang="EN-CA">     #(1 2 3)
                                          asArgumentsIn: [:a | a]</span></p>
                                      <p class="MsoNormal" style="margin-left:35.4pt"><span style="font-family:"Courier New"" lang="EN-CA">     #(1 2 3)
                                          asArgumentsIn: [42]</span></p>
                                      <p class="MsoNormal" style="margin-left:35.4pt"><span style="font-family:"Courier New"" lang="EN-CA">     'not ok'</span></p>
                                      <p class="MsoNormal" style="margin-left:35.4pt"><span style="font-family:"Courier New"" lang="EN-CA">     #(1 2 3)
                                          asArgumentsIn: [:a :b :c :d |
                                          a + b + c + d]</span></p>
                                      <p class="MsoNormal" style="margin-left:35.4pt"><span style="font-family:"Courier New"" lang="EN-CA">     "</span></p>
                                      <p class="MsoNormal" style="margin-left:35.4pt"><span style="font-family:"Courier New"" lang="EN-CA"> </span></p>
                                      <p class="MsoNormal" style="margin-left:35.4pt"><span style="font-family:"Courier New"" lang="EN-CA">     ^aBlock
                                          cullWithArguments: self
                                          asArray</span><span lang="EN-CA"></span></p>
                                      <p class="MsoNormal"><span lang="EN-CA"> </span></p>
                                      <p class="MsoNormal"><span lang="EN-CA">The difference is
                                          that it takes a list of any
                                          size and picks out the first
                                          items and binds them to the
                                          variables.</span></p>
                                      <p class="MsoNormal"><span lang="EN-CA">I use it often
                                          for CSV processing like</span></p>
                                      <p class="MsoNormal"><span lang="EN-CA">                </span><span lang="EN-CA">(line
                                          tokensBasedOn: $;)
                                          asArgumentsIn: [:first :second
                                          :y | … ].</span></p>
                                      <p class="MsoNormal"><span lang="EN-CA"> </span></p>
                                      <p class="MsoNormal"><span lang="EN-CA">I am just a bit
                                          unhappy with the name – it is
                                          too long. It reads ok though.</span></p>
                                      <p class="MsoNormal"><span lang="EN-CA">The pipe
                                          character is an interesting
                                          idea. I have to think about
                                          it.</span></p>
                                      <p class="MsoNormal"><span lang="EN-CA"> </span></p>
                                      <p class="MsoNormal"><span lang="EN-CA">I am use it for a
                                          while now and I am very happy
                                          with it.</span></p>
                                      <p class="MsoNormal"><span lang="EN-CA"> </span></p>
                                      <p class="MsoNormal"><span lang="EN-CA">Happy hacking,</span></p>
                                      <p class="MsoNormal"><span>Christian</span></p>
                                    </div>
                                  </div>
                                  <div lang="DE">
                                    <div>
                                      <p class="MsoNormal"><span> </span></p>
                                      <p class="MsoNormal"><span> </span></p>
                                      <div style="border-width:1pt
                                        medium medium;border-style:solid
                                        none none;padding:3pt 0cm
                                        0cm;border-color:rgb(225,225,225)
                                        currentcolor currentcolor">
                                        <p class="MsoNormal"><b>Von:</b>
                                          Cuis-dev <<a href="mailto:cuis-dev-bounces@lists.cuis.st" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">cuis-dev-bounces@lists.cuis.st</a>>
                                          <b>Im Auftrag von </b>Luciano
                                          Notarfrancesco via Cuis-dev<br/>
                                          <b>Gesendet:</b> Mittwoch, 21.
                                          Juni 2023 15:13<br/>
                                          <b>An:</b> Discussion of Cuis
                                          Smalltalk <<a href="mailto:cuis-dev@lists.cuis.st" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">cuis-dev@lists.cuis.st</a>><br/>
                                          <b>Cc:</b> Luciano
                                          Notarfrancesco <<a href="mailto:luchiano@gmail.com" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">luchiano@gmail.com</a>><br/>
                                          <b>Betreff:</b> [Cuis-dev]
                                          Methods that return multiple
                                          values</p>
                                      </div>
                                      <p class="MsoNormal"> </p>
                                      <p class="MsoNormal">Smalltalk
                                        doesn’t have a convention for
                                        methods returning multiple
                                        values, and I’m not aware of any
                                        implementation.</p>
                                      <div>
                                        <p class="MsoNormal">An example
                                          of such thing is the extended
                                          gcd: ‘a xgcd: b’ returns g, s,
                                          t where g is the gcd, and as +
                                          bt = g. Writing methods that
                                          return multiple values is easy
                                          with the curly brackets
                                          syntax, Integer>>#xgcd:
                                          ends with something like</p>
                                      </div>
                                      <div>
                                        <p class="MsoNormal">    ^ {g.
                                          s. t}</p>
                                      </div>
                                      <div>
                                        <p class="MsoNormal">But using
                                          sending messages that return
                                          multiple values is kind of
                                          annoying, I end up doing
                                          something like:</p>
                                      </div>
                                      <div>
                                        <p class="MsoNormal">    xgcd :=
                                          a xgcd: b.</p>
                                      </div>
                                      <div>
                                        <p class="MsoNormal">    g :=
                                          xgcd at: 1.</p>
                                      </div>
                                      <div>
                                        <p class="MsoNormal">    s :=
                                          xgcd at: 2.</p>
                                      </div>
                                      <div>
                                        <p class="MsoNormal">    t :=
                                          xgcd at: 3</p>
                                      </div>
                                      <div>
                                        <p class="MsoNormal">Some years
                                          ago I thought about using
                                          blocks for this, but I never
                                          tried it. Today I just did a
                                          little experiment implementing
                                          anArray | aBlock as ‘^ aBlock
                                          valueWithPossibleArgs: self’
                                          and I can do:</p>
                                      </div>
                                      <div>
                                        <p class="MsoNormal">    (a
                                          xgcd: b) | [:g :s :t| … ]</p>
                                      </div>
                                      <div>
                                        <p class="MsoNormal"> </p>
                                      </div>
                                      <div>
                                        <p class="MsoNormal">This is
                                          seems quite nice already, I
                                          guess I’ll start using it and
                                          see how it feels. But the
                                          point of this mail is not to
                                          show a solution, but to ask if
                                          anyone have thought about this
                                          or if they know any nicer
                                          solutions. Any ideas?</p>
                                      </div>
                                    </div>
                                  </div>
                                  -- <br/>
                                  Cuis-dev mailing list<br/>
                                  <a href="mailto:Cuis-dev@lists.cuis.st" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">Cuis-dev@lists.cuis.st</a><br/>
                                  <a href="https://lists.cuis.st/mailman/listinfo/cuis-dev" rel="noreferrer" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">https://lists.cuis.st/mailman/listinfo/cuis-dev</a><br/>
                                </blockquote>
                              </div>
                            </div>
                          </blockquote>
                        </blockquote>
                        <pre cols="72" style="font-family:monospace">--
❤️‍🔥🐰</pre>
                      </div>
                      -- <br/>
                      Cuis-dev mailing list<br/>
                      <a href="mailto:Cuis-dev@lists.cuis.st" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">Cuis-dev@lists.cuis.st</a><br/>
                      <a href="https://lists.cuis.st/mailman/listinfo/cuis-dev" rel="noreferrer" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">https://lists.cuis.st/mailman/listinfo/cuis-dev</a><br/>
                    </blockquote>
                  </div>
                </blockquote>
              </div>
            </div>
          </blockquote>
          <pre class="moz-signature" cols="72">--
❤️‍🔥🐰</pre>
        </blockquote>
        <pre class="moz-signature" cols="72">--
❤️‍🔥🐰</pre>
      </blockquote>
      <pre class="moz-signature" cols="72">--
❤️‍🔥🐰</pre>
    </blockquote>
    <pre class="moz-signature" cols="72">-- 
❤️‍🔥🐰</pre>
  
</body></html>