Not that bad, perhaps, but it still means we must have context
sensitive keywords before that is going to be possible (and in
general, I say, avoid those like the plague). It's also still
ambiguous, just less so: return (5); is perfectly legal today. Just
virtually never used.
Also, it's still not transparent, either: Outside of library-based ARM
blocks, foreach loops, etcetera, you MUST NOT bracketize your return
statements. But inside, you MUST bracket them. Or, inside closures,
unbracketed means local return, and bracketed means transparent
return. Eeeugh. That doesn't sound good.
I had a different idea:
Embrace CICE's dependence on the notion of SAM types. Make annotations
on a SAM type that convey:
1) This is a 'safe' closure - long returns are allowed.
2) This closure has no purpose for the return statement; so make the
return statement transparent. This requires the closure block to have
a 'void' return type (as there would be no way to return any value -
any usage of the return statement is automatically translated to a
long return).
All existing SAMs would automatically be unsafe (or did I get those
two terms mixed around?) - you could not long return/break/continue
out of them at all, which includes Comparator, but that's actually a
good thing, because while Collections.sort is safe, new TreeSet(some
comparator) isn't.
A SAM marked as safe/transparentreturn would have severe limitations
on how and where you're allowed to use it. Basically, you may not
assign them to any field or let them escape in any fashion other than
in a method that takes the exact same type, which will then have the
same restrictions. In practice I can't come up with many reasonable
use cases where these limitations would get in your way, and I can
think of plenty where these limitations give you a quick compile time
notification that what you're doing is buggy. Add block autoboxing and
you've got a BGGA/CICE hybrid with long returns but with no structural
types:
@SafeClosure public interface Each<T> {
public void do(T in);
}
public class Collections {
public static <T> void each(Iterable<T> iterable, Each<T> block) {
for ( T t : iterable ) block.do(t);
}
}
and then in your own code:
public void doesListContainBar(List<String> list) {
Collections.each(list, (String x) { if ( "bar".equals(x) ) return
true; }
return false;
}
(The closure block is autoboxed into an Each).
Haven't though this proposal all the way through (notably, I'm not
sure if the parser can remain LL(1), which needs to know the type of
every node in the AST before it knows anything about what identifier
corresponds to which type, so it must know that (String x) { /* code
*/ } is a closure before knowing about Each)
On Jan 15, 8:17 am, Viktor Klang <[email protected]> wrote:
> Actually,
>
> {
> //Do some crap
> return(yeahBaby);
>
> }
>
> isn't _that_ bad.
>
> On Thu, Jan 15, 2009 at 12:55 AM, Reinier Zwitserloot
> <[email protected]>wrote:
>
>
>
>
>
> > John:
>
> > return is a keyword. Making context sensitive keywords is a major
> > change.
>
> > Making () optional is an even bigger and more drastic change that's
> > going to run into lots of resistance.
>
> > But, most importantly:
>
> > return foobar;
>
> > would become ambiguous. You lose source backwards compatibility.
>
> > My personal intuition about the chances of that happening: Between
> > Hell freezing over and Tor making it through an entire posse without
> > coding.
>
> > On Jan 14, 7:19 pm, "John Nilsson" <[email protected]> wrote:
> > > On Wed, Jan 14, 2009 at 4:43 PM, Reinier Zwitserloot <[email protected]
> > >wrote:
>
> > > > You could graft long returns on
> > > > FCM or CICE later, but once you've already used 'return' for the
> > > > notion of a local return, then a future long return addition can never
> > > > be transparent - you'd have to have a different syntax for returning
> > > > out of the containing block, which all by itself is a pretty big
> > > > negative mark - that would mean that any attempt to add language
> > > > features by way of just writing a utility method are permanently
> > > > crippled by the fact that the 'return' syntax is not transparent, and
> > > > thus the need to know that something is a library call instead of a
> > > > language feature will always be a leaky abstraction.
>
> > > There are probably other ways to implement this. If you could, say, call
> > > methods without parenthesis like in Scala, and had a nice way of exposing
> > > those methods to the closure you could implement any behavior you want,
> > and
> > > call it what you want, instead of being restricted to return and friends.
>
> > > Implementing long return in this way is just the matter of throwing an
> > > exception and catch it at the right place.
>
> > > Something like
>
> > > abstract class ControlClosure<T>
> > > {
> > > protected T return(T retval) throws LongReturn<T>{
> > > throw new LongReturn<T>(retval);
> > > }
>
> > > }
>
> > > abstract class MyForeach<T>
> > > {
> > > public <RV> void foreach(#ControlClosure<RV>(void(T)LongReturn<RV>)
> > > closure);
>
> > > }
>
> > > BR,
> > > John
>
> --
> Viktor Klang
> Senior Systems Analyst
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "The
Java Posse" 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/javaposse?hl=en
-~----------~----~----~----~------~----~------~--~---