[Grace-core] Return

Kim Bruce kim at cs.pomona.edu
Mon May 30 11:46:52 PDT 2011


A few observations:

1.  A return from a normal block should just terminate it and return the value (just like a call to a parameterless function with a return in it).  That is essentially what should happen in the first example below, resulting in a 1 being passed along twice (with no ill effects).  I believe that semantics works fine for the second example as well as block is a closure that can be evaluated as many times as we like -- each time terminating and returning the value 1.

2.  Life gets complicated because we want to pass blocks as parameters to methods like "while cond do block".  In this case, performing the semantics listed above would give us the equivalent of a "continue" statement -- continue to the next iteration, as it would terminate the execution of the block, but not of the entire "while".  That is definitely NOT what we want.

In this case, return should perform more like an exception -- which it is, it is exceptional behavior that terminates the usual execution.  Defining "while" or "for" to catch that special exception is easily done (though nested whiles are still tricky!).
------

The problem is how to combine 1 and 2.  If we can encode it properly, it would seem simpler to always have a return throw a special exception and then in "normal" uses of a block, have the exception caught and simply return the value.  That may mean that an in-place use of a block calls a different kind of apply (of the parameterless function encoded by the block) than when things are passed in as parameters.

I don't have a good solution at this point, but wanted to write out my clarification of the issues.  Please correct if I've missed anything.

It seems like other folks who have dealt with these issues (smalltalk, newspeak?) should have addressed them.  Have they?

Kim



On May 29, 2011, at 7:07 PM, Michael Homer wrote:

> Hi,
> I understand that "return" inside a block should return from the
> enclosing method. What if that scope has already terminated? Is it a
> runtime error, or does it set the return value of Block.apply, pass
> silently, or something else?
> 
> Two code examples:
>  method foo() {
>    return { return 1 }
>  }
> and:
>  const a := object {
>    var block
>    method bar(block) {
>      self.block := block
>    }
>    method baz() {
>      self.block.apply()
>    }
>  }
>  method foo() {
>    a.bar { return 1 }
>    ...
>    a.baz()
>    ...
>  }
>  foo()
>  ...
>  a.baz()
> 
> The second example contains both possible action at a distance and
> double-return.
> 
> More generally, returning inside a block will cause execution of the
> scope invoking apply() to terminate as well, along with any others in
> between. Will the scopes be able to detect that?
> 
> I'm having difficulty finding an implementation strategy for this that
> covers all the possibilities. What I'm considering at the moment is
> roughly parallel to transforming "return x" to "block.hasReturned :=
> true ; raise Returns(v)" and writing the appropriate search in the
> exception handler, but that will still fall apart if the scope is
> either dead already or somehow not an ancestor of the apply() call. I
> have also considered providing the block with the creating scope's
> notional continuation, but that seems to have even more perverse
> results in these cases. I would like to be able to declare them to be
> an error or have undefined behaviour and just fail in the most
> convenient fashion.
> -Michael
> _______________________________________________
> Grace-core mailing list
> Grace-core at cecs.pdx.edu
> https://mailhost.cecs.pdx.edu/mailman/listinfo/grace-core



More information about the Grace-core mailing list