Tennent's book is quite old and talks about Pascal, I don't recall any
specific discussion of exceptions and exceptions were not part of
standard Pascal. So my guess is that any form of non-local jumps would
not be covered by Tennent directly. The princiople says that the
meaning of the code should not change if enclosed in a block, e.g.
while loop, but it means any type of block and therefore also a try
catch block.

So my reading is that any form of non-block structured jump is
excluded by the principle, i.e. no return, break, continue, or throw
statements. All these have to be simulated with a status variable.
Interestingly if an inner class was used instead of a block then a
control variable could be used and exceptions avoided all together:

enum Status { CONTINUE, BREAK; }

class Loop implements Method1< Void, Object > {
  Status status = CONTINUE;
  void breakLoop() { status = BREAK; }
}

class List {
  private Object[] data;
  ...
  void each( Loop l ) {
    for ( int i = 0; i < data.length && l.status == CONTINUE; i++ )
{ l.call( data[ i ] ); }
  }
}

// My favourite syntax follows!
list.each method( e ) { if ( someCondition ) { breakLoop() } };

On Oct 28, 9:38 am, Jochen Theodorou <[EMAIL PROTECTED]> wrote:
> hlovatt schrieb:
>
> > On Oct 21, 12:40 pm, "Neal Gafter" <[EMAIL PROTECTED]> wrote:
> >> A new exception hierarchy outside Throwable is necessary for closures to
> >> satisfy Tennent's Correspondence Principle, which as you know is a powerful
> >> litmus test for the expressive power of a language feature such as 
> >> closures.
>
> > Tennent used his Principle of Correspondence to argue against return,
> > break, and continue and instead advocated that every block should have
> > one exit point (end of block).
>
> sorry for warming up this thread after a week...
> It is a shame that I not yet had a chance of reading this... but maybe
> you can answer some questions.
>
> For example how did he define exit point? for example in this case
>
> def foo() { throw new RuntimeException("something") }
>
> while (true) {
>    foo()
>
> }
>
> you said "end of block", so I guess it has only one exit point... or
> does the foo() method have two then? If yes, wouldn't mean that
> exceptions are bad in Tennent's Correspondence Principle?
>
> But ok, let us say this has only one exit point.... Now, if we have a
> list and we want to proceed all elements until we meet a certain element
> and then stop processing, then I would write something like this:
>
> for (XY element : list) {
>     if (element==myBreakCondition) break
>     doSometing(element)
>
> }
>
> this has (at last) two exit point because of the loop, so I guess I
> would have to change the loop condition to do the additional check
>
> XY element
> for (Iterator it=list.iterator();
>       it.hasNext() && element!=myBreakCondition;) {
>    element = it.next()
>    doSomething(element)
>
> }
>
> but in case of a "closure" I could do this:
>
> list.each { XY element, LoopFlow flowControl ->
>    flowControl.breakIf(element==myBreakCondition)
>    doSometing(element)
>
> }
>
> where flowControl.breakIf would throw an exception, each (I will call
> each an iteration method, because it iterates over the list here) would
> catch that exception and use flowControl to check the exception... Would
> this still fulfill the "only one exit point per block" idea?
>
> Or the next question... if we say that a "closure syntax" overlaps with
> the syntax generally used by blocks, but if the "closure" is no block...
> does the principle then still apply to break/continue which have to be
> applied to the iteration method?
>
> Or let us say a break statement is not allowed in a "closure".. what
> does the principle say to this? I mean having one exit point per block
> is easily fulfilled with that, because it would not compile... Is the
> language to be considered as "less expressive" then, even if the break
> statement can be expressed by other elements that are not of syntactic
> nature? Or if I had a different syntactic element to do a break in a
> closure.. would the language then still be considered as "less powerful"?
>
> [...]
>
>
>
> > Having said that the block must be named, then the standard exception
> > mechanism can be used and this has the added advantage of providing a
> > compile time check for asynchronous use cases, e.g.:
>
> > // in the example below method { .. } is suggested short syntax for an
> > inner class (closure)
> > int i = 0;
> > iLoop: while ( true ) {
> >   invokeLater( method { ...; break iLoop; ... } ); // Error since
> > invokeLater doesn't catch iLoopBreakException
> >   }
> > }
>
> > The above example is caught at compile time because when expanded the
> > object passed to invokeLater throws a checked exception, iLoopBreak,
> > which isn't caught (and can't be caught because it is a local class)
> > by invokeLater. See previous return example for how break etc. are
> > expanded.
>
> on the other hand.... why is that a illegal usage of "break iLoop"? I
> mean ok, invokeLater might execute the "closure" in a different Thread,
> but what if not?
>
> I guess that's why the closure proposal expects the usage of "for" here:
>
> l1: while (true) {
>    l2: for each(element:list) {
>       if (element == myBreakCondition) break l1
>       break l2
>    }
>
> }
>
> from a pragmatic point of view I guess you would have to tell your
> iteration method that it needs to respond to "break l2", but not to
> "break l1". But of course I can not write:
>
> void for each(List list, MyClosure closure, Label label) {
>    label: for (x : list) closure.call()
>
> }
>
> and you can get even more fun with something like:
>
> l1: while (true) {
>    l2: for each(element:list) {
>       check (element == myBreakCondition, {break l1})
>       break l2
>    }
>
> }
>
> which means that check should execute the closure {break l1} if
> element==myBreakCondition. If we use the interface coercion that was
> proposed, then we would have to throw an compile time error here if the
> interface (for example Runnable) does not throw that exception. Or not?
> I mean according to your text above it must, because Runnable does not
> throw that exception and check would have to throw that exception too.
> But the advantage of the "for" keyword usage seems to be kind of lost here.
>
> So from looking at this from the perspective of a static type system
> where I want to have compile time checks as much as possible a checked
> exception would make sense to me. From the perspective of a API writer I
> get horrified but that ideas, because it means any method that somehow
> has to handle "closures" containing a break/continue would have to throw
> the exception. It would be equally annoying to he RemoteException for
> example. On the bytecode level it makes no difference, because the JVM
> is not checking if a exception is checked or not, only the Java compiler
> does.
>
> Regardless if new exception type is defined or not, I guess the API
> writers still get exposed to an implementation detail if they want to
> have their custom iteration methods which I think is bad...
>
> And even if there is a way to express the each without letting it
> explicitly catch and evaluate the exception (I would really like to know
> how to get around that), a checked exception would still mean, that at
> some point any API writer gets exposed to this implementation detail
> when they use the iteration method on their own.
>
> > I would also caution that adding support for non-local returns will
> > probably not be worth the trouble, since I doubt that non-local
> > returns will be used much. For example, what is a good use case
> > (remember that many languages don't have return etc. at all)?
>
> so you have no problem with break, but with return? I hope my check
> method example above did show you that it is not only "return", it is
> also break/continue to some extend.
>
> bye blackdrag
>
> --
> Jochen "blackdrag" Theodorou
> Groovy Tech Lead 
> (http://groovy.codehaus.org)http://blackdragsview.blogspot.com/http://www.g2one.com/


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "JVM 
Languages" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/jvm-languages?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to