<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
  </head>
  <body bgcolor="#ffffff" text="#000000">
    Hi Jaromir,<br>
    <br>
    On 5/16/2021 5:26 PM, Jaromir Matas via Cuis-dev wrote:
    <blockquote
cite="mid:BN7PR08MB38426B21A4020B8EDE322AC6EE2E9@BN7PR08MB3842.namprd08.prod.outlook.com"
      type="cite">
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <meta name="Generator" content="Microsoft Word 15 (filtered
        medium)">
      <style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
pre
        {mso-style-priority:99;
        mso-style-link:"HTML Preformatted Char";
        margin:0in;
        margin-bottom:.0001pt;
        font-size:10.0pt;
        font-family:"Courier New";
        color:black;}
span.HTMLPreformattedChar
        {mso-style-name:"HTML Preformatted Char";
        mso-style-priority:99;
        mso-style-link:"HTML Preformatted";
        font-family:"Courier New";
        color:black;}
.MsoChpDefault
        {mso-style-type:export-only;}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
--></style>
      <div class="WordSection1">
        <p class="MsoNormal">Hi Juan,</p>
        <p class="MsoNormal"><o:p> </o:p></p>
        <p class="MsoNormal">I'm enclosing an updated changeset (please
          disregard the previous one); I made a stupid assumption about
          #runUntilErrorOrReturnFrom:. The new changeset leaves it
          untouched and adds its replica called
          #runUnwindUntilErrorOrReturnFrom: with the required
          functionality.</p>
      </div>
    </blockquote>
    <br>
    I think you are right in the previous email, and we'd integrate your
    latest change.I have already checked that none of the tests we
    recently added breaks because of it. If you could turn some of the
    arguments you provide into tests, it would be great.<br>
    <br>
    <blockquote
cite="mid:BN7PR08MB38426B21A4020B8EDE322AC6EE2E9@BN7PR08MB3842.namprd08.prod.outlook.com"
      type="cite">
      <div class="WordSection1">
        <p class="MsoNormal">I'd like to point out a little issue with
          the proposed semantics of nested errors during termination:
        </p>
        <p class="MsoNormal"><o:p> </o:p></p>
        <p class="MsoNormal">Below’s a simple example. If you abandon
          the first debugger it means you want to terminate the
          execution and unwind the terminated process but an error
          happens during the unwind. You get another debugger reporting
          the error and asking you what to do next - to debug the error
          or proceed. But proceeding a termination really means to
          proceed with the *<b>unwind business only</b>* and not to
          proceed with the original computation. Here's my point:
          Hitting Proceed will resume the original computation beyond
          the unwind blocks but Abandon will only finish the unwind
          procedure which is exactly what we want. In Squeak I simply
          disabled the Proceed button but in Cuis I couldn't see such a
          simple solution so I left it unresolved.</p>
        <p class="MsoNormal"><o:p> </o:p></p>
        <p class="MsoNormal">[self error: 'x1'] ensure: [</p>
        <p class="MsoNormal">    [self error: 'x2'] ensure: [</p>
        <p class="MsoNormal">        Transcript show: '2'].</p>
        <p class="MsoNormal">    Transcript show: '1'].</p>
        <p class="MsoNormal">Transcript show: '0'</p>
        <p class="MsoNormal"><o:p> </o:p></p>
        <p class="MsoNormal">---> you want to see '21' but proceeding
          the debugger will give you '210' where '0' is printed outside
          of unwind blocks.</p>
        <p class="MsoNormal"><o:p> </o:p></p>
        <p class="MsoNormal">So just that you know there's still a
          little inconsistency in the termination semantics.</p>
        <p class="MsoNormal"><o:p> </o:p></p>
      </div>
    </blockquote>
    <br>
    I see. The issue is how to disable a button so it doesn't act? The
    simplest way is by saying `aButton lock: true`. We could add #enable
    and #disable to PluggableButtonMorph (calling self lock: ). Or
    perhaps call it #isEnabled: like in MenuItemMorph, although it is an
    ugly name. Can you prepare a change set like this? That would be
    great. I mean, I don't know where those calls should be made!<br>
    <br>
    <blockquote
cite="mid:BN7PR08MB38426B21A4020B8EDE322AC6EE2E9@BN7PR08MB3842.namprd08.prod.outlook.com"
      type="cite">
      <div class="WordSection1">
        <p class="MsoNormal">One more question: do you have an idea why
          BlockCannotReturn error is considered resumable? I'd say it's
          unresumable by definition…? Thanks :)</p>
      </div>
    </blockquote>
    <br>
    Well, that method is pretty old, and in the mean time, exception
    handling has gotten a lot better, thanks to several batches of
    improvements, latter ones by you. So, please provide a patch to
    change that, so it properly carries your initials.<br>
    <br>
    <blockquote
cite="mid:BN7PR08MB38426B21A4020B8EDE322AC6EE2E9@BN7PR08MB3842.namprd08.prod.outlook.com"
      type="cite">
      <div class="WordSection1">
        <p class="MsoNormal"><o:p> </o:p></p>
        <p class="MsoNormal">best regards,</p>
        <p class="MsoNormal"><o:p> </o:p></p>
        <p class="MsoNormal">Jaromir</p>
      </div>
    </blockquote>
    <br>
    Thanks again Jaromir for this amazing work.<br>
    <br>
    Cheers,<br>
    <br>
    <blockquote
cite="mid:BN7PR08MB38426B21A4020B8EDE322AC6EE2E9@BN7PR08MB3842.namprd08.prod.outlook.com"
      type="cite">
      <div class="WordSection1">
        <p class="MsoNormal"><o:p> </o:p></p>
        <div style="border-right: medium none; border-width: 1pt medium
          medium; border-style: solid none none; border-color: rgb(225,
          225, 225) -moz-use-text-color -moz-use-text-color; padding:
          3pt 0in 0in;">
          <p class="MsoNormal" style="border: medium none; padding:
            0in;"><b>From: </b><a moz-do-not-send="true"
              href="mailto:cuis-dev@lists.cuis.st">Jaromir Matas via
              Cuis-dev</a><br>
            <b>Sent: </b>Wednesday, May 12, 2021 17:02<br>
            <b>To: </b><a moz-do-not-send="true"
              href="mailto:cuis-dev@lists.cuis.st">Discussion of Cuis
              Smalltalk</a><br>
            <b>Cc: </b><a moz-do-not-send="true"
              href="mailto:mail@jaromir.net">Jaromir Matas</a>; <a
              moz-do-not-send="true" href="mailto:juan@jvuletich.org">
              Juan Vuletich</a>; <a moz-do-not-send="true"
              href="mailto:hernan.wilkinson@10pines.com">Hernan
              Wilkinson</a><br>
            <b>Subject: </b>Re: [Cuis-dev] Unwind mechanism during
            termination is broken and inconsistent</p>
        </div>
        <p class="MsoNormal"><o:p> </o:p></p>
        <p class="MsoNormal">Hi Juan,<o:p></o:p></p>
        <p class="MsoNormal"><o:p> </o:p></p>
        <p class="MsoNormal">I apologize for responding so late to your
          great comments. I felt I had to educate myself in error
          handling first :)<o:p></o:p></p>
        <p class="MsoNormal"><o:p> </o:p></p>
        <p class="MsoNormal">> m1<o:p></o:p></p>
        <p class="MsoNormal">>    | a |<o:p></o:p></p>
        <p class="MsoNormal">>    a := Array new: 3.<o:p></o:p></p>
        <p class="MsoNormal">>    self m2: a.<o:p></o:p></p>
        <p class="MsoNormal">>    a at: 3 put: true.<o:p></o:p></p>
        <p class="MsoNormal">>    a print.<o:p></o:p></p>
        <p class="MsoNormal">><o:p> </o:p></p>
        <p class="MsoNormal">>  m2: a   "A"<o:p></o:p></p>
        <p class="MsoNormal">>    [1 + 2] ensure: [<o:p></o:p></p>
        <p class="MsoNormal">>      [ 3 + 4 ] ensure: [    "*1"<o:p></o:p></p>
        <p class="MsoNormal">>        true ifTrue: [<o:p></o:p></p>
        <p class="MsoNormal">>           ^a at: 1 put: true ]]. "*2"<o:p></o:p></p>
        <p class="MsoNormal">>      a at: 2 put: true ]<o:p></o:p></p>
        <p class="MsoNormal">><o:p> </o:p></p>
        <p class="MsoNormal">>  In this example, the *1ensure is
          there only to guarantee that *2is ran, even if [3+4] happens
          to fail. If [3+4] it runs without problems, the result should
          be exactly the same as:<o:p></o:p></p>
        <p class="MsoNormal">><o:p> </o:p></p>
        <p class="MsoNormal">>  m2: a   "B"<o:p></o:p></p>
        <p class="MsoNormal">>    [1 + 2] ensure: [<o:p></o:p></p>
        <p class="MsoNormal">>      3 + 4.<o:p></o:p></p>
        <p class="MsoNormal">>      true ifTrue: [<o:p></o:p></p>
        <p class="MsoNormal">>        ^a at: 1 put: true ].<o:p></o:p></p>
        <p class="MsoNormal">>      a at: 2 put: true ]<o:p></o:p></p>
        <p class="MsoNormal">><o:p> </o:p></p>
        <p class="MsoNormal">>  Applying the same argument, the
          result should be the same as:<o:p></o:p></p>
        <p class="MsoNormal">><o:p> </o:p></p>
        <p class="MsoNormal">>  m2: a   "C"<o:p></o:p></p>
        <p class="MsoNormal">>    1 + 2.<o:p></o:p></p>
        <p class="MsoNormal">>    3 + 4.<o:p></o:p></p>
        <p class="MsoNormal">>    true ifTrue: [<o:p></o:p></p>
        <p class="MsoNormal">>      ^a at: 1 put: true ].<o:p></o:p></p>
        <p class="MsoNormal">>    a at: 2 put: true<o:p></o:p></p>
        <p class="MsoNormal">><o:p> </o:p></p>
        <p class="MsoNormal">>  In implementation C it is clear that
          a second isNil. So, the same should be the case for B and A.<o:p></o:p></p>
        <p class="MsoNormal"><o:p> </o:p></p>
        <p class="MsoNormal">This is a beautiful example! Thanks a lot,
          very enlightening. I fully agree, my suggestion was incorrect.
          The logic you are showing says to leave the block where the
          non-local return executes without unwinding but to continue
          unwinding after that block. Very interesting!<o:p></o:p></p>
        <p class="MsoNormal"><o:p> </o:p></p>
        <p class="MsoNormal">> x := nil.<o:p></o:p></p>
        <p class="MsoNormal">> [self error: 'x1'] ensure: [<o:p></o:p></p>
        <p class="MsoNormal">>   [self error: 'x2'] ensure: [<o:p></o:p></p>
        <p class="MsoNormal">> ​    [self error: 'x3'] ensure: [<o:p></o:p></p>
        <p class="MsoNormal">> ​      x:=3].<o:p></o:p></p>
        <p class="MsoNormal">> ​    x:=2].<o:p></o:p></p>
        <p class="MsoNormal">>   x:=1].<o:p></o:p></p>
        <p class="MsoNormal">> x<o:p></o:p></p>
        <p class="MsoNormal">><o:p> </o:p></p>
        <p class="MsoNormal">> I think this case is very similar to
          the one above.. For example, if we proceed the first debugger
          (the x1 error), the x2 debugger opens. If we abandon it, we
          are abandoning the execution of the first ensured block (that
          includes the x := 1 assignment at the end). So, no assignment
          is done. I think that the behavior of our fix is correct in
          this case. No need to simulate "resuming".<o:p></o:p></p>
        <p class="MsoNormal"><o:p> </o:p></p>
        <p class="MsoNormal">In this case I'd disagree. Abandoning is
          currently implemented and interpreted as terminating so I
          chose to follow this logic and made abandoning equivalent to
          sending #terminate, meaning the unwind will continue and
          execute the second error, open a second debugger etc. Please
          try out the enclosed changeset; it also follows the non-local
          logic you suggested above. We've also discussed the issue with
          Christoph Thiede here:
<a class="moz-txt-link-freetext" href="http://forum.world.st/Solving-multiple-termination-bugs-summary-proposal-tp5128285p5129113.html">http://forum.world.st/Solving-multiple-termination-bugs-summary-proposal-tp5128285p5129113.html</a><o:p></o:p></p>
        <p class="MsoNormal"><o:p> </o:p></p>
        <p class="MsoNormal">The main idea behind the extended version
          of #terminate is using the return value from
          #runUntilErrorOrReturnFrom: to continue the unwind based on
          the exception found.<o:p></o:p></p>
        <p class="MsoNormal"><o:p> </o:p></p>
        <p class="MsoNormal">I've also fixed a few minor bug in the
          current implementation:
          <o:p></o:p></p>
        <p class="MsoNormal"><o:p> </o:p></p>
        <p class="MsoNormal">1) using suspendedContext variable during
          unwind is an incorrect approach that may lead to leaving
          unterminated context chains behind which the garbage collector
          wouldn't recycle; I'm using a local temp 'top' instead.<o:p></o:p></p>
        <p class="MsoNormal"><o:p> </o:p></p>
        <p class="MsoNormal">2) I removed the part looking for an
          'inner' context halfway through execution - it's unnecessary
          and theoretically even incorrect - and use outerMost as the
          unwind context that needs to be completed.<o:p></o:p></p>
        <p class="MsoNormal"><o:p> </o:p></p>
        <p class="MsoNormal">3) the condition in the middle (`ifNil:
          [^self]`) became unnecessary after your fix.<o:p></o:p></p>
        <p class="MsoNormal"><o:p> </o:p></p>
        <p class="MsoNormal">4) there was an issue with infinite
          recursion in case of #cannotReturn and #doesNotUnderstand -
          this has been fixed by explicitly excluding the two exceptions
          from returning.<o:p></o:p></p>
        <p class="MsoNormal"><o:p> </o:p></p>
        <p class="MsoNormal">5) #cannotReturn generally causes a VM
          crash if it attempts to return - this is fixed by looping
          #cannotReturn back to itself and the way out leads via
          Abandoning the debugger window (even accidental pressing
          Proceed crashes your image so I guess it's worth fixing in
          every case)<o:p></o:p></p>
        <p class="MsoNormal"><o:p> </o:p></p>
        <p class="MsoNormal">6) #runUntilErrorOrReturnFrom: required a
          slight modification - I suggest either modify it or we can
          create a copy with this modified behavior; I chose to modify
          it because no current method would be affected by the change.<o:p></o:p></p>
        <p class="MsoNormal"><o:p> </o:p></p>
        <p class="MsoNormal">As another example illustrating the changes
          you can try:<o:p></o:p></p>
        <p class="MsoNormal"><o:p> </o:p></p>
        <p class="MsoNormal">    a := Array new: 4 withAll: false.<o:p></o:p></p>
        <p class="MsoNormal">    p := [<o:p></o:p></p>
        <p class="MsoNormal">             [<o:p></o:p></p>
        <p class="MsoNormal">            [] ensure: [<o:p></o:p></p>
        <p class="MsoNormal">                           [ ^2 ] ensure: [<o:p></o:p></p>
        <p class="MsoNormal">               
                                                a at: 1 put: true].<o:p></o:p></p>
        <p class="MsoNormal">                           a at: 2 put:
          true]<o:p></o:p></p>
        <p class="MsoNormal">                           ] ensure: [a at:
          3 put: true].<o:p></o:p></p>
        <p class="MsoNormal">                           a at: 4 put:
          true<o:p></o:p></p>
        <p class="MsoNormal">        ] newProcess.<o:p></o:p></p>
        <p class="MsoNormal">    p resume.<o:p></o:p></p>
        <p class="MsoNormal"><o:p> </o:p></p>
        <p class="MsoNormal">It crashes the image without amending
          #cannotReturn but works well with the enclosed changeset and
          returns
          <o:p></o:p></p>
        <p class="MsoNormal">correctly a equal to #(true false true
          false).<o:p></o:p></p>
        <p class="MsoNormal"><o:p> </o:p></p>
        <p class="MsoNormal">Also this example is catastrophic but dealt
          with safely with the new changeset:<o:p></o:p></p>
        <p class="MsoNormal"><o:p> </o:p></p>
        <p class="MsoNormal">   [^2] newProcess resume<o:p></o:p></p>
        <p class="MsoNormal"><o:p> </o:p></p>
        <p class="MsoNormal">I haven't built any testcases yet but I
          definitely plan to if you find this interesting.<o:p></o:p></p>
        <p class="MsoNormal"><o:p> </o:p></p>
        <p class="MsoNormal">Many thanks for discussing this issue; any
          comments will be greatly appreciated :)<o:p></o:p></p>
        <p class="MsoNormal"><o:p> </o:p></p>
        <p class="MsoNormal">best,<o:p></o:p></p>
        <p class="MsoNormal"><o:p> </o:p></p>
        <p class="MsoNormal">Jaromir<o:p></o:p></p>
        <p class="MsoNormal"><o:p> </o:p></p>
        <div style="border-right: medium none; border-width: 1pt medium
          medium; border-style: solid none none; border-color: rgb(225,
          225, 225) -moz-use-text-color -moz-use-text-color; padding:
          3pt 0in 0in;">
          <p class="MsoNormal"><b>From: </b><a moz-do-not-send="true"
              href="mailto:cuis-dev@lists.cuis.st">Juan Vuletich via
              Cuis-dev</a><br>
            <b>Sent: </b>Friday, April 30, 2021 19:32<br>
            <b>To: </b><a moz-do-not-send="true"
              href="mailto:cuis-dev@lists.cuis.st">Discussion of Cuis
              Smalltalk</a><br>
            <b>Cc: </b><a moz-do-not-send="true"
              href="mailto:juan@jvuletich.org">Juan Vuletich</a>; <a
              moz-do-not-send="true" href="mailto:mail@jaromir.net">
              Jaromir Matas</a>; <a moz-do-not-send="true"
              href="mailto:hernan.wilkinson@10pines.com">Hernan
              Wilkinson</a><br>
            <b>Subject: </b>Re: [Cuis-dev] Unwind mechanism during
            termination is broken and inconsistent<o:p></o:p></p>
        </div>
        <p class="MsoNormal"><o:p> </o:p></p>
        <p class="MsoNormal">Hi Jaromir,<br>
          <br>
          (inline)<br>
          On 4/30/2021 7:01 AM, Jaromir Matas via Cuis-dev wrote: <o:p></o:p></p>
        <blockquote style="margin-top: 5pt; margin-bottom: 5pt;">
          <p class="MsoNormal">Hi Juan,<o:p></o:p></p>
          <p class="MsoNormal"> <o:p></o:p></p>
          <p class="MsoNormal">Awesome! I remember the idea of using the
            result of #runUntilErrorOrReturnFrom crossed my mind for a
            fleeting moment… and then I lost it ;) With your permission
            I’d like to use your fix in my Squeak version as well.<o:p></o:p></p>
        </blockquote>
        <p class="MsoNormal" style="margin-bottom: 12pt;"><span
            style="color: black;">  <br>
            I'm glad you like it. Yes, of course. In these low level
            details, it is a good thing to have as much common code as
            possible!<br>
            <br>
            Besides, in general, all the code we publish for Cuis is MIT
            license, and free for any use.<br>
            <br>
            <o:p></o:p></span></p>
        <blockquote style="margin-top: 5pt; margin-bottom: 5pt;">
          <p class="MsoNormal">I’ve tried to rewrite your #<span
              style="color: black;">test1ATerminate
            </span>without the method calls – and indeed it passes… and
            that’s why I missed that – it was too simple; when using
            sends is where your fix comes to the rescue – THANKS!<o:p></o:p></p>
          <p class="MsoNormal"> <o:p></o:p></p>
          <p class="MsoNormal">    | p a |<o:p></o:p></p>
          <p class="MsoNormal">    a := Array new: 4 withAll: false.<o:p></o:p></p>
          <p class="MsoNormal">    p := [<o:p></o:p></p>
          <p class="MsoNormal">             [<o:p></o:p></p>
          <p class="MsoNormal">                              [ ] ensure:
            [<o:p></o:p></p>
          <p class="MsoNormal">           
                                             [Processor activeProcess
            suspend] ensure: [<o:p></o:p></p>
          <p class="MsoNormal">               
                                                       ^a at: 1 put:
            true].    "line L1"<o:p></o:p></p>
          <p class="MsoNormal">           
                                             a at: 2 put:
            true]                     "line L2"<o:p></o:p></p>
          <p class="MsoNormal">                              ] ensure:
            [a at: 3 put: true].<o:p></o:p></p>
          <p class="MsoNormal">                              a at: 4
            put: true<o:p></o:p></p>
          <p class="MsoNormal">        ] newProcess.<o:p></o:p></p>
          <p class="MsoNormal">    p resume.<o:p></o:p></p>
          <p class="MsoNormal">    Processor yield.<o:p></o:p></p>
          <p class="MsoNormal">    "make sure p is suspended and none of
            the unwind blocks has finished yet"<o:p></o:p></p>
          <p class="MsoNormal">    self assert: p isSuspended.<o:p></o:p></p>
          <p class="MsoNormal">    a noneSatisfy: [ :b | b ].<o:p></o:p></p>
          <p class="MsoNormal">    "now terminate the process and make
            sure all unwind blocks have finished"<o:p></o:p></p>
          <p class="MsoNormal">    p terminate.<o:p></o:p></p>
          <p class="MsoNormal">    self assert: p isTerminated.<o:p></o:p></p>
          <p class="MsoNormal">    self assert: a first & a third.<o:p></o:p></p>
          <p class="MsoNormal">    self assert: (a second | a fourth)
            not.<o:p></o:p></p>
        </blockquote>
        <p class="MsoNormal" style="margin-bottom: 12pt;"><span
            style="color: black;"><br>
            Yes it does. I just thought that a more real-life like test
            of non local returns should also include actual method
            calls!<o:p></o:p></span></p>
        <blockquote style="margin-top: 5pt; margin-bottom: 5pt;">
          <p class="MsoNormal">I’d like to raise a question here: I feel
            the second item, on line L2 should ideally execute too
            because it’s inside an unwind block halfway through it’s
            termination. The problem is though the non-local return at
            line L1 invokes it’s own unwind algorithm in
            #resume:through: which ignores halfway through unwind blocks
            – the reason for that is #resume:through: operates on the
            active process’s stack which makes it extremely difficult to
            unwind halfway through blocks. I tried to apply a similar
            tactics like in termination (control the unwind from another
            stack) and it works well but it’s very intrusive… I may open
            a separate discussion on that later to share the results. Do
            you think it may be worth exploring or it’s just not worth
            the bother?<o:p></o:p></p>
        </blockquote>
        <p class="MsoNormal" style="margin-bottom: 12pt;"><span
            style="color: black;">  <br>
            Well. This is not just in the case of process #terminate,
            right? To play with this without involving process handling,
            but including actual method calls I just tried this:<br>
            <br>
            m1<br>
                | a |<br>
                a := Array new: 3.<br>
                self m2: a.<br>
                a at: 3 put: true.<br>
                a print.<br>
            <br>
            m2: a      "A"<br>
                [1 + 2] ensure: [<br>
                    [ 3 + 4 ] ensure: [       "*1"<br>
                        true ifTrue: [<br>
                            ^a at: 1 put: true ]]. "*2"<br>
                    a at: 2 put: true ]<br>
            <br>
            In this example, the *1ensure is there only to guarantee
            that *2is ran, even if [3+4] happens to fail. If [3+4] it
            runs without problems, the result should be exactly the same
            as:<br>
            <br>
            m2: a     "B"<br>
                [1 + 2] ensure: [<br>
                    3 + 4.<br>
                    true ifTrue: [<br>
                        ^a at: 1 put: true ].<br>
                    a at: 2 put: true ]<br>
            <br>
            Applying the same argument, the result should be the same
            as:<br>
            <br>
            m2: a     "C"<br>
                1 + 2.<br>
                3 + 4.<br>
                true ifTrue: [<br>
                    ^a at: 1 put: true ].<br>
                a at: 2 put: true<br>
            <br>
            In implementation C it is clear that a second isNil. So, the
            same should be the case for B and A.<br>
            <br>
            I think that an ensured block should be guaranteed to run
            without external interference. But if it decides on its own
            to exit before running all its statements, it is it's own
            decision.<br>
            <br>
            <o:p></o:p></span></p>
        <blockquote style="margin-top: 5pt; margin-bottom: 5pt;">
          <p class="MsoNormal">Another issue: I considered using the
            error part of the result of #runUntilErrorOrReturnFrom: to
            deal with situations like this (careful – crashes the Cuis
            image without the terminate fix; with the fix it works
            “ok”):<o:p></o:p></p>
          <p class="MsoNormal"> <o:p></o:p></p>
          <p class="MsoNormal">x := nil.<o:p></o:p></p>
          <p class="MsoNormal">[self error: 'x1'] ensure: [<o:p></o:p></p>
          <p class="MsoNormal">    [self error: 'x2'] ensure: [<o:p></o:p></p>
          <p class="MsoNormal">        [self error: 'x3'] ensure: [<o:p></o:p></p>
          <p class="MsoNormal">            x:=3].<o:p></o:p></p>
          <p class="MsoNormal">        x:=2].<o:p></o:p></p>
          <p class="MsoNormal">    x:=1].<o:p></o:p></p>
          <p class="MsoNormal">x<o:p></o:p></p>
          <p class="MsoNormal"> <o:p></o:p></p>
          <p class="MsoNormal">Here you have nested errors and the
            question is: If we abandon the Debugger window, what do we
            want to see as a result? Without the fix the image crashes
            badly with unwind errors, with the fix however the Debugger
            closes without unwinding – it’s a consequence of #
            runUntilErrorOrReturnFrom: behavior – it returns errors
            rather than opens a debugger (and leaves the decision with
            the user). So what do we want to see as a result – keep
            opening debugger windows and abandoning them manually or
            ignoring the errors and executing the assignments? That
            sounds like “resuming” rather than abandoning to me so at
            the moment I don’t know and will have to think about it. I
            just didn’t want to complicate the #terminate prematurely :)<o:p></o:p></p>
        </blockquote>
        <p class="MsoNormal" style="margin-bottom: 12pt;"><span
            style="color: black;">  <br>
            I think this case is very similar to the one above.. For
            example, if we proceed the first debugger (the x1 error),
            the x2 debugger opens. If we abandon it, we are abandoning
            the execution of the first ensured block (that includes the
            x := 1 assignment at the end). So, no assignment is done. I
            think that the behavior of our fix is correct in this case.
            No need to simulate "resuming".<br>
            <br>
            <o:p></o:p></span></p>
        <blockquote style="margin-top: 5pt; margin-bottom: 5pt;">
          <p class="MsoNormal">Juan, many thanks again, I’ll study your
            tests and learn from them.<o:p></o:p></p>
        </blockquote>
        <p class="MsoNormal" style="margin-bottom: 12pt;"><span
            style="color: black;"><br>
            I'm happy to be of help. There's not nothing in those tests
            that could be new to you. All I did was to add nested method
            calls, and add the #resume cases, that already did work with
            the fix. Let me thank you. You did a great analysis of the
            issues at hand, and your fix is a great contribution.<br>
            <br>
            I'll integrate it right now. If any further analysis
            provides additional changes, we'll integrate them too.<br>
             <o:p></o:p></span></p>
        <blockquote style="margin-top: 5pt; margin-bottom: 5pt;">
          <p class="MsoNormal">Best regards,<o:p></o:p></p>
          <p class="MsoNormal"> <o:p></o:p></p>
          <p class="MsoNormal">jaromir<o:p></o:p></p>
          <p class="MsoNormal"> <o:p></o:p></p>
        </blockquote>
        <p class="MsoNormal" style="margin-bottom: 12pt;"><span
            style="color: black;"><br>
            Cheers,<o:p></o:p></span></p>
        <pre>-- </pre>
        <pre>Juan Vuletich</pre>
        <pre><a moz-do-not-send="true" href="http://www.cuis-smalltalk.org">www.cuis-smalltalk.org</a></pre>
        <pre><a moz-do-not-send="true" href="https://github.com/Cuis-Smalltalk/Cuis-Smalltalk-Dev">https://github.com/Cuis-Smalltalk/Cuis-Smalltalk-Dev</a></pre>
        <pre><a moz-do-not-send="true" href="https://github.com/jvuletich">https://github.com/jvuletich</a></pre>
        <pre><a moz-do-not-send="true" href="https://www.linkedin.com/in/juan-vuletich-75611b3">https://www.linkedin.com/in/juan-vuletich-75611b3</a></pre>
        <pre>@JuanVuletich</pre>
        <p class="MsoNormal"><span style="font-size: 10pt; font-family:
            "Courier New"; color: black;"><o:p> </o:p></span></p>
        <p class="MsoNormal"><o:p> </o:p></p>
      </div>
    </blockquote>
    <br>
    <br>
    <pre class="moz-signature" cols="72">-- 
Juan Vuletich
<a class="moz-txt-link-abbreviated" href="http://www.cuis-smalltalk.org">www.cuis-smalltalk.org</a>
<a class="moz-txt-link-freetext" href="https://github.com/Cuis-Smalltalk/Cuis-Smalltalk-Dev">https://github.com/Cuis-Smalltalk/Cuis-Smalltalk-Dev</a>
<a class="moz-txt-link-freetext" href="https://github.com/jvuletich">https://github.com/jvuletich</a>
<a class="moz-txt-link-freetext" href="https://www.linkedin.com/in/juan-vuletich-75611b3">https://www.linkedin.com/in/juan-vuletich-75611b3</a>
@JuanVuletich</pre>
  </body>
</html>