<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Le lun. 30 mars 2020 à 23:04, Levente Uzonyi <<a href="mailto:leves@caesar.elte.hu">leves@caesar.elte.hu</a>> a écrit :<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hi Christoph,<br>
<br>
On Mon, 30 Mar 2020, Thiede, Christoph wrote:<br>
<br>
> <br>
> Hi Nicolas,<br>
> <br>
> <br>
> I don't see your point of #doWhileTrue: being not idiomatic. What exactly do you mean by that except for "unfamiliar"?<br>
> <br></blockquote><div><br></div><div>
<div><span><span>idiomatic: using, containing, or denoting expressions that are natural to a native speaker.</span></span> <br></div><div>So whileTrue: is natural for a native Smalltalker</div><div>(I don't know a lot of natives, it's not my first programming language neither, but you get it).</div><div>
<div><br></div><div>#whileTrue should not be considered independently of the more powerful #whileTrue:</div><div>This later construct is not easily found in other languages where I often have to insert a if/break/continue/cycle which is much less expressive.<br></div><div>Normally, you learn #whileTrue: which has many more senders, then once learned, #whileTrue. shouldn't sound un-natural.</div>

</div><div><br></div></div><div>I didn't even notice the presence of doWhileTrue: until today!</div><div>I just stumbled upon it while searching for #cacheDuring:.<br></div><div>I think that it's not part of other Smalltalk dialects, never saw it used in Visualworks, Dolphin.</div><div>A vast majority of us should agree that it does not qualify as idiomatic.<br></div><div>IMO it does not add enough value to whileTrue.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
> <br>
> However, I agree that the names are confusing, compared to #whileTrue: etc.<br>
> <br>
> +1 for naming them #repeatWhile: and #repeatUntil: instead!<br>
> <br>
> <br>
> > But that still means that we have two ways to express exactly the same thing, which by first principle should not be<br>
> <br>
> > (economy of implementation, of tests, of documentation, etc... small is beautiful !).<br>
> <br>
> Well, that's another a question of semantics, again. :) Remember my examples about #ifNotNil:/#==> etc.? Convenience methods support ease of writing and reading.<br>
> <br>
> > Really, not kidding?<br>
> The example is taken from BookMorph >> #saveOnUrlPage:. I did not read it in context, too ^^<br>
> <br>
> > Is the following better? > <br>
> > [newPlace := self getNewPlace.<br>
> > file:= ServerFile new fullPath: newPlace.<br>
> > file exists] whileTrue<br>
> <br>
> In my opinion, #repeatUntil: would still be better :)<br>
> <br>
> > Note that I did not add non local block return in the middle of the block... > It was in the original method, doWhileTrue did not solve it.<br>
> <br>
> I was referring to blockReturn in the bytecode sense. Here is another example of confusing blockReturns:<br>
> <br>
> (foo satisfiesSomeCondition or: [|baz|<br>
>     baz := bar asBaz.<br>
>     foo cacheDuring: [<br>
>         baz satisfiesSomeOtherCondition]])<br>
>             ifTrue: [...]<br>
> <br>
> Hard to follow the control flow, isn't it? If I have the choice, I avoid these statements and use blocks,<br>
<br>
Whether or not the above example is okay or not depends on what [...] is. <br>
For example, if it's simply ^self, then the use of #or: is unnecessary and <br>
the computation which reduces legibility can be moved out to the main flow <br>
of the method.<br>
<br>
> either) to pass a piece of code to another object and compose control flows,<br>
> or) to explicitly pass a value to be evaluated lazily.<br>
> Both at once can be confusing. I think there is a good reason why there is no syntax for blockReturn like we have one for methodReturn (^).<br>
<br>
There is no syntax for blockReturn because it wouldn't be possible to use it.<br>
<br>
<br>
Levente<br>
<br>
> <br>
> Best,<br>
> Christoph<br>
> <br>
> _________________________________________________________________________________________________________________________________________________________________________________________________________________________________<br>
> Von: Squeak-dev <<a href="mailto:squeak-dev-bounces@lists.squeakfoundation.org" target="_blank">squeak-dev-bounces@lists.squeakfoundation.org</a>> im Auftrag von Nicolas Cellier <<a href="mailto:nicolas.cellier.aka.nice@gmail.com" target="_blank">nicolas.cellier.aka.nice@gmail.com</a>><br>
> Gesendet: Montag, 30. März 2020 20:56:43<br>
> An: The general-purpose Squeak developers list<br>
> Betreff: Re: [squeak-dev] #doWhileTrue: (was: The Trunk: System-nice.1149.mcz)  <br>
> <br>
> <br>
> Le lun. 30 mars 2020 à 19:58, Thiede, Christoph <<a href="mailto:Christoph.Thiede@student.hpi.uni-potsdam.de" target="_blank">Christoph.Thiede@student.hpi.uni-potsdam.de</a>> a écrit :<br>
><br>
>       Hi Nicolas,<br>
> <br>
><br>
>       > There is no other sender of doWhileFalse: doWhileTrue: and my advice would be to deprecate them. YAGNI.<br>
> <br>
> <br>
> So my image actually contains around two dozen senders of #doWhileTrue: and #doWhileFalse: (Squot, Pheno and some of my own code). As mentioned somewhere else in the past, I actually like them and find them very useful.<br>
> <br>
> In my opinion, many senders of #whileTrue and #whileFalse should be refactored to use #doWhileTrue:/#doWhileFalse:. Here is a random example:<br>
> <br>
> [newPlace := self getNewPlace.<br>
> dir := ServerFile new fullPath: newPlace.<br>
> (dir includesKey: dir fileName)] whileTrue.<br>
> <br>
> I find that's ugly and counter-intuitive! I would rewrite this in the following way:<br>
> <br>
> [newPlace := self getNewPlace.<br>
> dir := ServerFile new fullPath: newPlace]<br>
>     doWhileTrue: [dir includesKey: dir fileName].<br>
> <br>
> <br>
> The first thing that upsets me is that they are not idiomatic. #whileTrue: and in a lesser way #whileTrue are.<br>
> The second thing that upsets me is that the names are REALLY too close to #whileTrue:<br>
> So at first, I was confused by the fact that they looked like synonyms.<br>
> Then I wondered exactly the same, what the hell has to be true?<br>
> Especially when the sole sender in trunk is [] doWhileTrue: true ;)<br>
> <br>
> IMO, they might be better spelled #repeatWhile: and #repeatUntil:<br>
> But that still means that we have two ways to express exactly the same thing, which by first principle should not be<br>
> (economy of implementation, of tests, of documentation, etc... small is beautiful !).<br>
> <br>
> We might discuss which is more readable, maybe<br>
> <br>
> [newPlace := self getNewPlace.<br>
> dir := ServerFile new fullPath: newPlace]<br>
>     repeatWhile: [dir includesKey: dir fileName].<br>
> <br>
> is more revealing than:<br>
> <br>
> [newPlace := self getNewPlace.<br>
> dir := ServerFile new fullPath: newPlace.<br>
> (dir includesKey: dir fileName)] whileTrue.<br>
> <br>
> IMO, it's a biased example, because the whole snippet is un-comprehensible.<br>
> So a ServerFile behaves like a ServerDirectory (from which it inherits...), oh nice (???).<br>
> And a ServerFile which would includes some item with same name as itself would mean that the file already exists...<br>
> Really, not kidding?<br>
> <br>
> So IMO that's what makes the snippet illegible, not whileTrue.<br>
> Is the following better?<br>
> <br>
> [newPlace := self getNewPlace.<br>
> file:= ServerFile new fullPath: newPlace.<br>
> file exists] whileTrue<br>
> <br>
> Anyway, the second one is there for such a long time that you can't expunge it that easily. It's idiomatic...<br>
> <br>
> The latter just reads easier. blockReturns in multi-statement blocks are not really intuitive.<br>
> <br>
> <br>
> Note that I did not add non local block return in the middle of the block...<br>
> It was in the original method, doWhileTrue did not solve it.<br>
><br>
>       In the first version, when scanning the method quickly, I read "okay, something with places and directories is done, while true ...," I wonder "what has to be true?" and have to look back to the end of the block<br>
>       and find the beginning of the last statement.<br>
> But in the second version, I read "okay, something with places and directories is done, while that directory matches this specific condition." This version directly draws my attention to the important condition.<br>
> <br>
> Happy to hear your counterarguments :-)<br>
> <br>
> Best,<br>
> Christoph<br>
> <br>
> _________________________________________________________________________________________________________________________________________________________________________________________________________________________________<br>
> Von: Squeak-dev <<a href="mailto:squeak-dev-bounces@lists.squeakfoundation.org" target="_blank">squeak-dev-bounces@lists.squeakfoundation.org</a>> im Auftrag von <a href="mailto:commits@source.squeak.org" target="_blank">commits@source.squeak.org</a> <<a href="mailto:commits@source.squeak.org" target="_blank">commits@source.squeak.org</a>><br>
> Gesendet: Montag, 30. März 2020 12:51 Uhr<br>
> An: <a href="mailto:squeak-dev@lists.squeakfoundation.org" target="_blank">squeak-dev@lists.squeakfoundation.org</a>; <a href="mailto:packages@lists.squeakfoundation.org" target="_blank">packages@lists.squeakfoundation.org</a><br>
> Betreff: [squeak-dev] The Trunk: System-nice.1149.mcz  <br>
> Nicolas Cellier uploaded a new version of System to project The Trunk:<br>
> <a href="http://source.squeak.org/trunk/System-nice.1149.mcz" rel="noreferrer" target="_blank">http://source.squeak.org/trunk/System-nice.1149.mcz</a><br>
> <br>
> ==================== Summary ====================<br>
> <br>
> Name: System-nice.1149<br>
> Author: nice<br>
> Time: 30 March 2020, 12:50:26.196366 pm<br>
> UUID: ece53b0b-24d2-4d4b-bc91-6794a661f886<br>
> Ancestors: System-ul.1148<br>
> <br>
> avoid neuron storming [...] doWhileTrue: true, it just means [...] repeat<br>
> <br>
> There is no other sender of doWhileFalse: doWhileTrue: and my advice would be to deprecate them. YAGNI.<br>
> <br>
> =============== Diff against System-ul.1148 ===============<br>
> <br>
> Item was changed:<br>
>   ----- Method: MOFile>>searchByHash: (in category 'experimental') -----<br>
>   searchByHash: aString<br>
>          | hashValue nstr index incr key |<br>
>          hashValue :=  self hashPjw: aString.<br>
>          incr := 1 + (hashValue \\ (hashTableSize -2)).<br>
>          index := (hashValue \\ hashTableSize) .<br>
>          [        nstr := (hashTable at: index +1 ).<br>
>                  nstr = 0 ifTrue: [^nil].<br>
>                  key := self originalString: nstr.<br>
>                  key = aString ifTrue: [^self translatedString: nstr].<br>
>                  index >= (hashTableSize - incr)<br>
>                                  ifTrue: [index := index - (hashTableSize - incr)  ]<br>
>                                  ifFalse:[index := index + incr].       <br>
> +        ] repeat!<br>
> -        ] doWhileTrue: true.!<br>
> <br>
> <br>
> <br>
> <br>
><br>
</blockquote></div></div>