[squeak-dev] Escaping from loops in scripts
Nicolas Cellier
nicolas.cellier.aka.nice at gmail.com
Sun Dec 9 20:22:22 UTC 2018
Hi Tobias,
I don't want to pay the burden of making own class/methods, I just want to
write a dumb and dirty script.
But to answer to myself, what I asked is already in the image:
BlockClosure>>valueWithExit
self value: [ ^nil ]
It would be more convenient with a return value, but for now it's ok.
Le dim. 9 déc. 2018 à 14:08, Tobias Pape <Das.Linux at gmx.de> a écrit :
> Hi Nicolas,
>
>
> > On 09.12.2018, at 11:37, Nicolas Cellier <
> nicolas.cellier.aka.nice at gmail.com> wrote:
> >
> > Hi all,
> > when writing scripts, I often need the ability to interrupt a loop.
> > This is the traditional break instruction of C/Python or more advanced
> exit of FORTRAN/ADA (we can tell from which nexted loop we exit).
> >
> > I could use exceptions, but then handling exit from nested loops is
> tricky (see below).
> > One possible way to do it in Smalltalk is to use blocks, and interrupt
> with non local return.
> >
>
>
> My way would be to use at most one method per loop and have an exit block
> then, like so
>
>
> A>>run: x
> |y z |
> y = 0.
> z := x
> [z < 10] whileTrue:
> [y := self foobar: z ifExit: [ ^y].
> z := z + 1]
> ^ y
>
> A>> foobar: x ifExit: aBlock
>
> | y |
> y := x.
> [y isOdd] whileTrue:
> [y := y + 2.
> " somehting something"
> y > 3 ifTrue: aBlock]
> ^ y
>
> Best regards
> -Tobias
>
> > ref
> http://lists.gnu.org/archive/html/help-smalltalk/2008-06/msg00077.html
> >
> > Object>>escape: aBlock
> > "Give the ability to exit execution of aBlock by returning control
> to sender.
> > aBlock will take an argument, which is a door for returning control.
> > This is useful for breaking a loop, for example:
> > self escape: [:exit | someCollection do: [:e | e
> fullfilSomeCondition ifTrue: [exit value]. e doSometing]]"
> > aBlock value: [^self]
> >
> > | sum |
> > sum := 0.
> > self escape: [:exitOuterLoop | someCollection do: [:e |
> > self escape: [:exitInnerLoop | someOtherCollection do: [:e2 |
> > e2 > e ifTrue: [exitOuterLoop value].
> > e2 = e ifTrue: [exitInnerLoop value].
> > sum := sum + e]]]].
> > ^sum
> >
> > We can also use the escape: inside the loop to avoid chained
> ifTrue:ifFalse:
> > but it's then convenient to let escape: return a value:
> >
> > Object>>escape: aBlock
> > ^aBlock value: [:result | ^result]
> >
> > aCollection collect: [:e |
> > e escape: [:return |
> > e < 0 ifTrue: [return value: e].
> > e > 20 ifTrue: [return value: 401 ln].
> > (e squared + 1) ln]]
> >
> > ref
> https://stackoverflow.com/questions/7547750/smalltalk-block-can-i-explicitly-set-the-returning-value-and-stop-executing-th/11532045#11532045
> >
> > At that time, I found that amusing, now I find it useful.
> > I don't see such support in trunk image, could we add it?
> > Do you think of a better name?
> > (not setjmp: please)
> >
> > Unless you come with better alternatives... One thing that is
> questionable is that the receiver of escape: is void (escape: is a utility).
> >
> > There is
> https://stackoverflow.com/questions/52683795/gnu-smalltalk-break-from-whiletrue-loop-without-return/52702174#52702174
> > It start looking like FORTRAN/ADA exit instruction with explicit naming
> of loop but I don't like it better.
> >
> > Maybe sending the message to the block itself sounds less arbitrary.
> >
> > BlockClosure>>handleExit
> > ^self value: [:result | ^result]
> >
> > | sum |
> > sum := 0.
> > [:exitOuterLoop | someCollection do: [:e |
> > [:exitInnerLoop | someOtherCollection do: [:e2 |
> > e2 > e ifTrue: [exitOuterLoop value: nil].
> > e2 = e ifTrue: [exitInnerLoop value: nil].
> > sum := sum + e]] handleExit ]] handleExit.
> > ^sum
> >
> > Though, I don't find such post-fixing satisfactory: exitOuterLoop and
> handleExit are too far from each other... Especially in scripts that tend
> to be longer than ordinary methods (we don't want to factor every quick and
> dirty procedure into proper classes/methods when there is no reuse
> objective or when they are too specific).
> >
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20181209/ddf26125/attachment.html>
More information about the Squeak-dev
mailing list
|