The Source for Java Technology Collaboration
User: Password:



Rémi Forax

Rémi Forax's Blog

java.lang.Unreachable as type argument

Posted by forax on November 21, 2006 at 02:13 AM | Comments (7)

The closure proposal specifies a new type java.lang.Undeclarable that can be used as a return type of a method to indicates that this method never returns. All instructions after a call to a method that returns Undeclarable is unreachable, by example :

  Undeclarable throwAnIOException(String message) throws Exception {
    throw new IOException(message);
  }
  ...
  void foo() {
    ...
    throwAnIOException("oups");
    return; // this code is unreachable
  }

This type is needed because in the closure proposal, the closure (return) type is infered from the type its last expression. So if the last expression is a throw, the compiler will infer java.lang.Undeclarable.

Now, the proposal also provides an example of code in which Unreachable is used as argument of a type variable.

  interface NullaryFunction<T, throws E> {
    T invoke() throws E;
  }
  NullaryFunction<Unreachable,null> thrower = {=> throw new AssertionError(); };
'Return' type variable

But Undeclarable can only be used as a return type and the compiler will not enforce that.
I propose to tag the type variable with the keyword return to say that type variable can only be used as return type, with the following rules

  • Its a compile error to use Undeclarable as a type variable not tagged by return.
  • Its a compile time error to use a type variable tagged by return in any other places that as return type

With these rules, the previous example will be:

  interface NullaryFunction<return T, throws E> {
    T invoke() throws E;
  }
  NullaryFunction<Unreachable,null> thrower = {=> throw new AssertionError(); };

The closure proposal already describes a resticted type variable: the throws type variable. A type variable tagged by throws that can be only used in throws clause and used a special inference mecanism. So adding a return type variable is just another way to restrict a type variable.

Self types

In a recent blog entry, Peter ahé's describes Self types, he write in an answer to one of my comment, "The this type variable is only type-safe in covariant places". So like Undeclarable, if we want to use this as a type argument, the corresponding type variable should be tagged by return.

I wait you comments.
Rémi


Bookmark blog post: del.icio.us del.icio.us Digg Digg DZone DZone Furl Furl Reddit Reddit
Comments
Comments are listed in date ascending order (oldest first) | Post Comment

  • Do those that support the various closure proposals ever have to maintain other people's code? Every proposal I've seen so far, even for simple examples, is close to unreadable (except for the author and a few well-above-average developers) and is becoming a lot heavier than the boilerplate imposed by inner classes. The drawbacks of (anonymous) inner classes (mainly passing local variables) can usually be worked around without too much effort.

    It seems that all closure proposals are driven by a desire to write less code, without thinking about maintaining it. Most modern IDEs (my preference is for IntelliJ) automatically fill in the boilerplate so I don't lose time writing it; however, it's generally easy enough to jump back into readable code after a while.

    - Chris

    Posted by: chris_e_brown on November 21, 2006 at 04:52 AM

  • It looks like most of the [perceived] complexity with closures is related to exceptions - personally I use exceptions as little as possible, because it's hard to be consistent with them. So hopefully closures will appear simple to me. I'll probably end up learning the exception semantics over time anyway, because of the hundreds of future 'wtfblog' posts on it (generics anyone?)..

    I expect that our clever little Integrated Development Environments will provide automatic refactoring between closures and classes (named or anonymous), so I don't think Chris Brown has anything real to worry about.

    I hope the refactorings work in both directions - in IDEA and Eclipse you can currently automatically refactor an anonymous class to a named class, but not vice versa, which is a pain.

    IDEs could possibly also present the source to a closure as if it were a named class, etc., without actually changing the source. Like folding, but in reverse. Maybe it could be called, um, unfolding.

    Posted by: ricky_clarkson on November 21, 2006 at 06:28 AM

  • Chris, they obviously don't maintain code... Otherwise they would work on things the community is actually asking like fixing generics, autoboxing and other half baked 1.5 features. Maybe porting them to Java ME (even CDC doesn't have them yet) or better yet! Working on things the community is actually begging for like MVM! But why waste time when we can invent cool new things ;-(

    This post is very interesting though for someone like myself who thinks closures are really unnecessary complexity! Thanks, when I last blogged about closures I didn't even imagine this particular drawback.

    Posted by: vprise on November 22, 2006 at 08:02 AM


  • If the objective is to notify the compiler that a method never returns, why not add a runtime anotation called, for example, NeverReturns and not a new type?


    class Sample {
    @NeverReturns
    public static void main(String[] args) {
    while (true)
    System.out.println("This method will never end");
    }
    }


    I think an annotation and keeping the void type is clearer than returning java.lang.Unreachable.


    My two cents.

    Posted by: rivasdiaz on November 22, 2006 at 08:32 AM

  • I dont't see any advantage on this "closure" (I'll call this "first-class function")! This is already existing in some of the languages supported by the JVM and I don't want that to be in the Java language.

    Why on hearth did people call this "closure", i' reminds me the name closure of prolog which is realy all about "closing" the stack backtracing! And not about specifying a function !

    What I want for JDK7 is a realtime genericity support. This would be much more usefull for all the MDA toolkit for instance.

    Anybody cares about specifying functions in an object language ?

    Did I miss something, if so post a real world example that show the real benefit (not an helloworld) and the same optimized code using anonymous/inner classes (genericity and anotations featured).

    Posted by: bjb on November 22, 2006 at 10:04 AM

  • Using Groovy-style syntax since I can't track the latest Java 7 recommendations easily, here are some practical examples:
    upperCaseNames = names.map{name -> name.toUpperCase()}
    db.open{connection -> /* do stuff with the connection */}
    Or other things along those lines. Imagine doing those with anonymous classes. Or image never being able to use local vars in your for loops that were declared outside the loops unless you called them "final" first. Or other things like that. Done right, closures lead to stronger and more writable and more readable code. That's if they are done right, of course.
    And people forgetting to close connections or writing bugs due to algorithms being more manual across several lines are very much real world issues that people encounter every day.
    Also, "closures" is term that's been in use for decades. (Wikipedia traces the term at least to the 80s based on a quick skim.) They didn't invent it here.

    Posted by: tompalmer on November 22, 2006 at 01:38 PM

  • As for the "return T" recommendation, I don't know. Hard to get into all the details from day to day. I just hope something usable to everyday programmers comes out in the end. (I understand that specs and plans get more nitpicky than everyday coding. So hopefully it won't be this hard. I just hope they don't forget the everyday and what it will look like.)

    Posted by: tompalmer on November 22, 2006 at 02:01 PM





Powered by
Movable Type 3.01D
 Feed java.net RSS Feeds