<br><font size=2 face="sans-serif">Benoit St-Jean wrote:</font>
<br><font size=2 face="sans-serif">&nbsp; &gt;&gt;For instance why would you write:</font>
<br>
<br><font size=2 face="sans-serif">&nbsp; &gt;&gt;anObject isFoo</font>
<br><font size=2 face="sans-serif">&nbsp; &gt;&gt; &nbsp; ifTrue: [^#foo]</font>
<br><font size=2 face="sans-serif">&nbsp; &gt;&gt; &nbsp; ifFalse: [^#bar]</font>
<br>
<br><font size=2 face="sans-serif">&nbsp; &gt;&gt;instead of:</font>
<br>
<br><font size=2 face="sans-serif">&nbsp; &gt;&gt;^anObject isFoo</font>
<br><font size=2 face="sans-serif">&nbsp; &gt;&gt; &nbsp; ifTrue: [#foo]</font>
<br><font size=2 face="sans-serif">&nbsp; &gt;&gt; &nbsp; ifFalse: [#bar]</font>
<br>
<br><font size=2 face="sans-serif">&nbsp; &gt;&gt;I always thought that clean blocks was the way to go and</font>
<br><font size=2 face="sans-serif">&nbsp; &gt;&gt;that you should always try to avoid returning from</font>
<br><font size=2 face="sans-serif">&nbsp; &gt;&gt;inside a block when possible, so what's the deal here?</font>
<br>
<br><font size=2 face="sans-serif">Yes, I think a block without a return is the better solution,</font>
<br><font size=2 face="sans-serif">BUT: &nbsp;<b>ifTrue:ifFalse: </b>is inlined, and I think the blocks are</font>
<br><font size=2 face="sans-serif">removed due to inlining. So the difference does not matter here.</font>
<br>
<br><font size=2 face="sans-serif">Nevertheless, the use of return is a question of style and I prefer</font>
<br><font size=2 face="sans-serif">&nbsp; &nbsp; ^anObject isFoo</font>
<br><font size=2 face="sans-serif">&nbsp; &nbsp; &nbsp; &nbsp;ifTrue: []</font>
<br><font size=2 face="sans-serif">&nbsp; &nbsp; &nbsp; &nbsp;ifFalse: []</font>
<br><font size=2 face="sans-serif">This form clearly states the fact that we will return,</font>
<br><font size=2 face="sans-serif">while</font>
<br><font size=2 face="sans-serif">&nbsp; &nbsp; &nbsp;anObject isFoo</font>
<br><font size=2 face="sans-serif">&nbsp; &nbsp; &nbsp; &nbsp;ifTrue: [ &lt;...&gt; ^#foo]</font>
<br><font size=2 face="sans-serif">&nbsp; &nbsp; &nbsp; &nbsp;ifFalse: [&lt;...&gt; ^#bar]</font>
<br><font size=2 face="sans-serif">hides this fact. </font>
<br>
<br>
<br>
<br><font size=2 face="sans-serif">To the best of my understanding, there is only one</font>
<br><font size=2 face="sans-serif">situation that requires a return within a block:</font>
<br>
<br><font size=2 face="sans-serif">&nbsp; foo</font>
<br><font size=2 face="sans-serif">&nbsp; &nbsp; self doSomethingOnFailure: [^false].</font>
<br><font size=2 face="sans-serif">&nbsp; &nbsp; self doSomthingElse.</font>
<br><font size=2 face="sans-serif">&nbsp; &nbsp; ^true</font>
<br>
<br><font size=2 face="sans-serif">&nbsp; doSomethingOnFailue: failureBlock</font>
<br><font size=2 face="sans-serif">&nbsp; &nbsp; &nbsp;&lt;...&gt;</font>
<br><font size=2 face="sans-serif">&nbsp; &nbsp; &nbsp;failureBlock value</font>
<br><font size=2 face="sans-serif">&nbsp; &nbsp; &nbsp;&lt;...&gt;</font>
<br>
<br><font size=2 face="sans-serif">This is essentially a nonlocal jump: The evaluation of</font>
<br><font size=2 face="sans-serif">&quot;failureBlock value&quot; causes the method <b>foo</b> to be left</font>
<br><font size=2 face="sans-serif">with result value &nbsp;false. That is, from doSomethinOnFailue:</font>
<br><font size=2 face="sans-serif">we jump back to the place where &nbsp;foo &nbsp;was called. &nbsp;</font>
<br>
<br>
<br><font size=2 face="sans-serif">&nbsp; &gt;&gt;BTW, if you look at senders of ifTrue:ifFalse: (or</font>
<br><font size=2 face="sans-serif">&nbsp; &gt;&gt;vice-versa) you only get a few methods... &nbsp;Is it</font>
<br><font size=2 face="sans-serif">&nbsp; &gt;&gt;broken or that is the normal &quot;behavior&quot; since that</font>
<br><font size=2 face="sans-serif">&nbsp; &gt;&gt;&quot;message&quot; is inlined and not reaaly a message send?</font>
<br>
<br>
<br><font size=2 face="sans-serif">Yes, inlined methods can not found by &quot;senders of... &quot;.</font>
<br><font size=2 face="sans-serif">&quot;senders of ... &quot; scans compiled methods for attached</font>
<br><font size=2 face="sans-serif">message symbols, and for an inlined message no</font>
<br><font size=2 face="sans-serif">message symbol is attached.</font>
<br>
<br><font size=2 face="sans-serif">It is sometimes asked whether methods that are inlined</font>
<br><font size=2 face="sans-serif">by the compiler are needed in the image at all. They</font>
<br><font size=2 face="sans-serif">are needed because they can be sent with a perform.</font>
<br>
<br><font size=2 face="sans-serif">Try this (in some class): </font>
<br>
<br><font size=2 face="sans-serif">test</font>
<br>
<br><font size=2 face="sans-serif">&nbsp; &nbsp;| string idx |</font>
<br>
<br><font size=2 face="sans-serif">&nbsp; &nbsp; string := 'hello&gt;&gt;Benoit'.</font>
<br><font size=2 face="sans-serif">&nbsp; &nbsp; idx := 1.</font>
<br><font size=2 face="sans-serif">&nbsp; &nbsp; [(string at: idx) = $&gt;]</font>
<br><font size=2 face="sans-serif">&nbsp; &nbsp; &nbsp; &nbsp;perform: #whileFalse: &nbsp;with: [idx := idx + 1]. </font>
<br><font size=2 face="sans-serif">&nbsp; &nbsp; ^string copyFrom: idx to: string size. </font>
<br>
<br><font size=2 face="sans-serif">This method will be found as a sender of &nbsp;#whileFalse:.</font>
<br>
<br><font size=2 face="sans-serif">When you insert a &nbsp;&quot;self halt.&quot; &nbsp;in &nbsp;BlockContext&gt;&gt;whileFalse:</font>
<br><font size=2 face="sans-serif">and execute the method, the debugger will stop at the halt. &nbsp;</font>
<br>
<br><font size=2 face="sans-serif">The following example is a bit tricky: </font>
<br>
<br><font size=2 face="sans-serif">&nbsp; &nbsp;| string idx |</font>
<br>
<br><font size=2 face="sans-serif">&nbsp; &nbsp; string := 'hello&gt;&gt;Benoit'.</font>
<br><font size=2 face="sans-serif">&nbsp; &nbsp; idx := 1.</font>
<br><font size=2 face="sans-serif">&nbsp; &nbsp; [(string at: idx) = $&gt;]</font>
<br><font size=2 face="sans-serif">&nbsp; &nbsp; &nbsp; &nbsp;whileFalse: [idx := idx + 1]; &nbsp;&quot; NOT inlined &quot;</font>
<br><font size=2 face="sans-serif">&nbsp; &nbsp; &nbsp; &nbsp;whileTrue: [idx := idx + 1]. &nbsp; &quot; inlined &quot;</font>
<br><font size=2 face="sans-serif">&nbsp; &nbsp; string copyFrom: idx to: string size.</font>
<br>
<br><font size=2 face="sans-serif">Squeak 3.2 does not accept this as valid code (<b>why ??</b>), some</font>
<br><font size=2 face="sans-serif">other Smalltalks do. Those who do (Visual Works and IBM Smalltalk),</font>
<br><font size=2 face="sans-serif">create a message send instruction for the first block (that is,</font>
<br><font size=2 face="sans-serif">the method BlockContext&gt;&gt;whileFalse: will be executed) &nbsp;and</font>
<br><font size=2 face="sans-serif">inlined code for the second block (the method Blockcontext&gt;&gt;whileTrue:</font>
<br><font size=2 face="sans-serif">will not be executed). The well-known Digitalk Smalltalk V/286 crashed </font>
<br><font size=2 face="sans-serif">with a general protection fault, but that was a compiler bug that could</font>
<br><font size=2 face="sans-serif">be fixed after decompilation of the compiler.</font>
<br>
<br><font size=2 face="sans-serif">Bye</font>
<br>
<br><font size=2 face="sans-serif">Boris <br>
<br>
msg &nbsp;systems ag<br>
Fraunhoferstraße 9<br>
85737 Ismaning<br>
<br>
Tel.: (+89) 96 101 546<br>
mailto: Boris_Gaertner@msg.de</font>