Shouldn't there be an Exit Block Statement in Smalltalk 
Author Message
 Shouldn't there be an Exit Block Statement in Smalltalk

Putting a '^' in a block exits the block from the method context.

What is missing a statement that just returns from the block. Such a
statement would be useful in constructs like "Guard Clauses" (Beck) that can
be put inside blocks.

An addition to the language would make it standard across all Smalltalks.

I think '^^' will do nicely.

Uh-Oh better hide from the language police.



Wed, 18 Jun 1902 08:00:00 GMT  
 Shouldn't there be an Exit Block Statement in Smalltalk

Quote:

>Putting a '^' in a block exits the block from the method context.
>What is missing a statement that just returns from the block.

Perhaps it's this way to encourage the use of many small methods instead of
using a number of blocks within a single method.  :)

Ian

----------------------------------------------------------------------------

----------------------------------------------------------------------------



Wed, 18 Jun 1902 08:00:00 GMT  
 Shouldn't there be an Exit Block Statement in Smalltalk

Quote:

>Putting a '^' in a block exits the block from the method context.

I used to think this too, but I changed my mind some time ago.
Actually you would want two things, if you wanted any:
        - exit the block
        - exit this invocation of this block
For a simple block they wold both basically be the same, but
for a block invoked multiple times (e.g. collection do:)
it would just go on to the next invocation.

However, for a number of reasons the increased complexity
would be a hinderance:
        - the fact that you would need two actions,
          as indicated above, and that they would do
          slightly different things based on the invoker
        - the fact that you now have to look more carefully
          at a block to see how it works.  The current
          design is simple.  You see a "^xxx" and
          you know it returns from the method.  The fact
          that its inside a block can mostly be ignored,
          it just "looks right".
        - As invoker of a block, you only have one
          return value to care about, the "result of
          the block".  If you could terminate the block
          you would somehow have to deal with
          two return values, not sure how one would
          go about this.

Quote:

>What is missing a statement that just returns from the block. Such a
>statement would be useful in constructs like "Guard Clauses" (Beck) that can
>be put inside blocks.

>An addition to the language would make it standard across all Smalltalks.

>I think '^^' will do nicely.

>Uh-Oh better hide from the language police.

=================================================================
Dennis Smith, MaSc  --  Cherniak Software Development Corporation
400-10 Commerce Valley Dr E, Thornhill ON Canada  L3T 7N7
Phone: 905.771.7011      FAX: 905.771.6288



Wed, 18 Jun 1902 08:00:00 GMT  
 Shouldn't there be an Exit Block Statement in Smalltalk

Quote:

> Putting a '^' in a block exits the block from the method context.

> What is missing a statement that just returns from the block. Such a
> statement would be useful in constructs like "Guard Clauses" (Beck) that can
> be put inside blocks.

> An addition to the language would make it standard across all Smalltalks.

> I think '^^' will do nicely.

> Uh-Oh better hide from the language police.

Faisal, I think you are talking about a C break like feature.
if so, there have been a few ideas and suggestions{*filter*} around.
one of them - BlockClosure>>valueWithExit (originally by Vassily Bykov?) has made it to VW3.0, so check it out.
I'm afraid most people don't find it very useful though, simply because it is sufficient and so easy to simply put the Block in another separate method. for example, there are no senders of valueWithExit in the base image.

it reminds me of the case with case (statements).
people came up with many inventive solutions, standing to challenge simply because it is fun when this wonderful malleable Smalltalk environment is crying for you to play with it. at the end of the day, there's very rare occasions where such solutions are called for.

Benny Sadeh



Wed, 18 Jun 1902 08:00:00 GMT  
 Shouldn't there be an Exit Block Statement in Smalltalk



[...]

Quote:
> Faisal, I think you are talking about a C break like feature.
> if so, there have been a few ideas and suggestions{*filter*} around.
> one of them - BlockClosure>>valueWithExit (originally by Vassily Bykov?)

has made it to VW3.0, so check it out.
Quote:
> I'm afraid most people don't find it very useful though, simply because it

is sufficient and so easy to simply put the Block in another separate
method. for example, there are no senders of valueWithExit in the base
image.
[...]

Here is an example that illustrates that this may be good idea:

Current approach:

[condition1
    ifTrue: [x]
    ifFalse:
        [condition2
            ifTrue: [y]
            ifFalse:
                [condition 3
                    ifTrue: [z]
                    ifFalse: [A]]]

With the new approach it can be rewritten as:

[condition1 ifTrue: [^^x].
condition2 ifTrue: [^^y].
condition3 ifTrue: [^^z].
A]

As you can see, it makes the code much cleaner. Now, I can always move the
code into a method and call that method from the block. But I am creating a
method just to make code in a block look neat not because I inherently need
a method. This is just extra work.

I don't know about others but I sure seem to run into this situation quite a
bit (perhaps because I am a liberal user of exception handling). And usually
I do end up creating a new method.

The fact that someone implemented such a feature supports that there is a
need for a block return statement.

Also, by moving the code to a method, a previously static block may become a
context block due to a reference to 'self'.

Faisal



Wed, 18 Jun 1902 08:00:00 GMT  
 Shouldn't there be an Exit Block Statement in Smalltalk
Faisal,

the problem I see with this is, how is Smalltalk to determine which
block is being exited from?  If just the immediately enclosing
block, then your code would seem to always evaluate to A (because
the block returns are inside blocks passed to the ifTrue: message).

I don't see how you can have it float to higher blocks, because
this whole thing might be wrapped in some other block(s), like
another ifTrue: [] or a cursor doWhile: [] or some such.

Perhaps I'm missing something.  I agree that I've often wanted to
be able to return from a block, but it seems a bit complicated!

-Christopher

Quote:

> Here is an example that illustrates that this may be good idea:

> Current approach:

> [condition1
>     ifTrue: [x]
>     ifFalse:
>         [condition2
>             ifTrue: [y]
>             ifFalse:
>                 [condition 3
>                     ifTrue: [z]
>                     ifFalse: [A]]]

> With the new approach it can be rewritten as:

> [condition1 ifTrue: [^^x].
> condition2 ifTrue: [^^y].
> condition3 ifTrue: [^^z].
> A]

> As you can see, it makes the code much cleaner. Now, I can always move the
> code into a method and call that method from the block. But I am creating a
> method just to make code in a block look neat not because I inherently need
> a method. This is just extra work.

> I don't know about others but I sure seem to run into this situation quite a
> bit (perhaps because I am a liberal user of exception handling). And usually
> I do end up creating a new method.

> The fact that someone implemented such a feature supports that there is a
> need for a block return statement.

> Also, by moving the code to a method, a previously static block may become a
> context block due to a reference to 'self'.

> Faisal



Wed, 18 Jun 1902 08:00:00 GMT  
 Shouldn't there be an Exit Block Statement in Smalltalk
You are right. I wan't  really thinking through all the implications of
this.

Faisal


Quote:
> Faisal,

> the problem I see with this is, how is Smalltalk to determine which
> block is being exited from?  If just the immediately enclosing
> block, then your code would seem to always evaluate to A (because
> the block returns are inside blocks passed to the ifTrue: message).

> I don't see how you can have it float to higher blocks, because
> this whole thing might be wrapped in some other block(s), like
> another ifTrue: [] or a cursor doWhile: [] or some such.

> Perhaps I'm missing something.  I agree that I've often wanted to
> be able to return from a block, but it seems a bit complicated!

> -Christopher


> > Here is an example that illustrates that this may be good idea:

> > Current approach:

> > [condition1
> >     ifTrue: [x]
> >     ifFalse:
> >         [condition2
> >             ifTrue: [y]
> >             ifFalse:
> >                 [condition 3
> >                     ifTrue: [z]
> >                     ifFalse: [A]]]

> > With the new approach it can be rewritten as:

> > [condition1 ifTrue: [^^x].
> > condition2 ifTrue: [^^y].
> > condition3 ifTrue: [^^z].
> > A]

> > As you can see, it makes the code much cleaner. Now, I can always move
the
> > code into a method and call that method from the block. But I am
creating a
> > method just to make code in a block look neat not because I inherently
need
> > a method. This is just extra work.

> > I don't know about others but I sure seem to run into this situation
quite a
> > bit (perhaps because I am a liberal user of exception handling). And
usually
> > I do end up creating a new method.

> > The fact that someone implemented such a feature supports that there is
a
> > need for a block return statement.

> > Also, by moving the code to a method, a previously static block may
become a
> > context block due to a reference to 'self'.

> > Faisal



Wed, 18 Jun 1902 08:00:00 GMT  
 Shouldn't there be an Exit Block Statement in Smalltalk

Quote:

> I don't see how you can have it float to higher blocks, because
> this whole thing might be wrapped in some other block(s), like
> another ifTrue: [] or a cursor doWhile: [] or some such.

A simple and manageable solution for someone who *really* wants this
are exit procedures Benny Sadeh mentioned.  However, #valueWithExit in
VW 3.0 is not what it should be.  IMHO, the exit procedure should take
an argument that gets returned from the block it exits.  Otherwise the
whole thing is just half as useful.  BlockClosure>>#valueWithExit
should read

  valueWithExit
    ^self value: [:answer | ^answer]

And then Faisal's example would be

  [:exit |
  condition1 ifTrue: [exit value: x].
  condition2 ifTrue: [exit value: y].
  condition3 ifTrue: [exit value: z].
  A] valueWithExit

--Vassili

--

The Object People    <http://www.objectpeople.com>
  "Any sufficiently complicated C or fortran program contains
  an ad-hoc, informally-specified bug-ridden slow implementation
  of half of Common Lisp."  --Greenspun's Tenth Rule of Programming



Wed, 18 Jun 1902 08:00:00 GMT  
 Shouldn't there be an Exit Block Statement in Smalltalk

Quote:


> > I don't see how you can have it float to higher blocks, because
> > this whole thing might be wrapped in some other block(s), like
> > another ifTrue: [] or a cursor doWhile: [] or some such.

> A simple and manageable solution for someone who *really* wants this
> are exit procedures Benny Sadeh mentioned.  However, #valueWithExit in
> VW 3.0 is not what it should be.  IMHO, the exit procedure should take
> an argument that gets returned from the block it exits.  Otherwise the
> whole thing is just half as useful.  BlockClosure>>#valueWithExit
> should read

>   valueWithExit
>     ^self value: [:answer | ^answer]

> And then Faisal's example would be

>   [:exit |
>   condition1 ifTrue: [exit value: x].
>   condition2 ifTrue: [exit value: y].
>   condition3 ifTrue: [exit value: z].
>   A] valueWithExit

> --

oh-oh, I think somebody has made a {*filter*}oo!
of course Vassili is absolutely right (sorry for misspelling your name before :-()

in my VW2.5.2 image I have one implementation (which I can't remember who did I steal it from ...) which follows Vassili's prescription:

BlockClosure>>valueWithExit
 "Answer the result of evaluating the receiver, a oneArgumentBlock.
 An early return can be taken in the body of the receiver by sending #value: to the argument.

 We can use other control forms without requiring leaving the entire method.
 Too bad blocks don't have multi-exit semantics. However we can achieve it with:
 result := [:exit |
 a isNil ifTrue: [exit value:nil].
 b isNil ifTrue: [exit value:nil].
 c isNil ifTrue: [exit value:nil]] valueWithExit.
 self doMoreStuffHerePresumablyUsing: result.

 Note in the example if a isNil, there's no penalty for the other branches.
 Also, note no 'helper' objects need to be instantiated.
 Finally, the test expression can have blocks or anything you like."

 ^self value: [:x | ^x]

on the other hand, in the official VWNC3.0 and VW5i it shows:

BlockClosure>>valueWithExit
 "Evaluate the block represented by the receiver supplied with an argument that when sent value will cause execution to leave the block"

 ^self value: [^nil]

two comments to the VW implementors: (are you listening Elliot? )
1. why did you choose to settle for less? please revert to the 'original' implementation.
2. this method is certainly not self documenting, and it isn't used anywhere in the image, so how is anyone to make sense of it? how about adding a nice comment/explanation such as in the above first implementation?

Benny Sadeh



Wed, 18 Jun 1902 08:00:00 GMT  
 Shouldn't there be an Exit Block Statement in Smalltalk

Quote:

> ...
> anway heres another entry in the "neat ways to do bad things in smalltalk just
> because we can" department:
> ...
> (most will think i'm nuts to do this i'm sure :)

you got that one right :-)


Wed, 18 Jun 1902 08:00:00 GMT  
 
 [ 10 post ] 

 Relevant Pages 

1. gets blocking when it shouldn't

2. Quit LabVIEW (Exit) stops program but doesn't exit

3. sys.exit() doesn't exit

4. exiting eval'ed script without exiting app

5. expect doesn't exit exiting processes, help me

6. Help! Deleted files I shouldn't have

7. Shouldn't I do so? [copyright law]

8. Shouldn't this be constant space?

9. shouldn't STOP?

10. Mistery: JGE taken while it shouldn't have been

11. Mystery: JGE taken but it shouldn't have happened

12. instead of C++ shouldn't ms have used masm for win95

 

 
Powered by phpBB® Forum Software