The Source for Java Technology Collaboration
User: Password:



Rémi Forax's Blog

November 2006 Archives


java.lang.Unreachable as type argument

Posted by forax on November 21, 2006 at 02:13 AM | Permalink | 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



How far is fidji - Reloaded

Posted by forax on November 15, 2006 at 06:24 AM | Permalink | Comments (3)

This blog is an infrared echo to Matthias Ernst's last post titled "How far is fidji".

  1. get rid of checked exceptions :
    For me the problem is not checked/unchecked exception but the fact that in the JDK, some places abuse of checked exceptions like reflection, rmi etc. I agree with matthias that it could be easy to add a keyword to transform or not xhecked exception to runtime exception but a checked exception like IOException is vital for a decent programming language. You can't reuse a lib that performs networking and get rid of checked exceptions.
  2. fill the void :
    One proposed annotation of the JSR 305 is about that.
  3. add type inference for locals:
    I totally agree with matthias, you don't have to declare local variable if you won't. And i hope it will be included into dolphin. C# has already that with the keyword var.
  4. add reliable closing of iterators in the for-each loop:
    I prefer to use a JDK method for doing that, by example, using the proposed for syntax by neal gafter.
  5. Resource literals: The ressource section of the JSR 277 is not a mecanism close to what matthias want.

So I don't know how far we are from Fidji but i know that we are not so far from Java :)



Stupid question: Why the creation of array of parametrized type is unsafe ?

Posted by forax on November 09, 2006 at 02:19 AM | Permalink | Comments (8)

I don't understand why array creation of array of parametrized type is forbidden by the JLS.

Let me take an example :

  public class Holder<E> {
    public void set(E element) {
      this.element=element;
    }
    public E get() {
      return element;
    }
    private final E element;
  }
  ...
  Holder<String>[] holders=new Holder<String>[4];
  for(int i=0;i(); 

Why the array creation new Holder<String>[4] is rejected by all java compiler as unsafe ?

The JLS3 clearly doesn't allow that in section 10.3, about array creation "It is a compile-time error if the element type is not a reifiable type". Okay, the JLS prohibits that but i don't understand why. Is there a Java guru that can explain me why ?

The generics tutorial written by Gilad Bracha provides an example that show that there is a problem when an array is assigned to an Object. In short, the following code is unsafe :

  Object[] array=holders; 
  holders[0]=new Object();
  System.out.println(holder[0].get()); // try to call get on an Object

That's true, but i don't agree with the diagnostic. For me, it's the convertion to Object[] (Object[] array=holders) which is unsafe and not the array creation.

I wonder if the spec can't be change to something like this :

It's unsafe to convert an array of parametrized type to Object, Object[], Serializable and Cloneable.

This condition is far less restrictive and permits to use parametrized array in lot of usefull use cases. By example, the following code will be safe.

 public static void main(String[] args) throws Throwable {
   final InetAddress host=InetAddress.getByName("www.playboy.com");
    
   int poolSize=4;
   ExecutorService executor = 
     Executors.newFixedThreadPool(poolSize);
   Future<Long>[] futures=new Future<Long>[poolSize]; //ok
   for(int i=0;i<poolSize;i++) {
     futures[i]=executor.submit(new Callable<Long>() {
       public Long call() throws Exception {
         long time=System.nanoTime();
         host.isReachable(2000);
         return System.nanoTime()-time;
       }
     });
   }
   executor.shutdown();
   for(Future<Long> future:futures)
    System.out.println("reach "+host+" in "+future.get()+" ns");
 }

What do you think about that ?
Rémi



Reified generics in Java

Posted by forax on November 06, 2006 at 02:23 AM | Permalink | Comments (8)

Neal Gafter post a blog entry about adding reified generics to Java. I likethat proposal mostly because developpers will have the choice betweeen reified or not reified generics.

About the syntax, i think it's better to use an anotation than to re-use the keyword class. Annotating a type variable is not currently allowed but it seems that the upcoming JSR 308 will allow that.

 class ArrayList<@Reified E> {
   ...
 }
instead of
 class ArrayList<class E> {
   ...
 }

The big question is why tagging the type variable and not the parametrized type.
I'm not sure that allowing to declare on a same parametrized type refied type variable and non refied is a good idea, because i don't see a use case.

 class HashMap<@Reified K,V> {

 }

Here, HashMap is not refiable because V is not refiable. So what is the need of half reified type ?

Else, i not sure about the fact that allowing reified generics requires to change collection interfaces. Allowing reified interfaces will just allow safe cast/instanceof, i wonder if it worth all problems linked to the introduction of a new collection hierarchy. It's perhaps up to a collection implementor to decide if a collection implentation will use or not reified generics.

To end, i've recently read a paper of Mirko Viroli about how to represent wildcard types at compiler level but i'am not aware of any work about that at VM level.

Rémi





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