The longer I look into the draft specification the more mysterious it looks to me. This cannot be the final specification of a new language feature. Does anybody know where the feature is actually specified?
Just as an example: page 13 of the draft spec (dated April 27, 2001) says:
cons(new IOException(), cons(new Error(), nil())) // of type: Seq<Throwable>
The generics compiler, however, rejects it saying:
cons<A>(A,Seq<A>) cannot be applied to (IOException,Seq<Error>)
Frankly said, I think, the compiler is right and the draft specification is wrong. Seemingly the idea of type parameter inference is that each actual argument type is a subtype of the corresponding formal argument type that was found by means of type parameter inference.
In the example above, if type Throwable were deduced for the type variable A, then the first formal method argument were of type Throwable and the actual argument would be of a subtype, namely IOException. Fine. But the second formal method argument would then be Seq<Throwable> and the actual argument is a Seq<Error>, which is not a subtype of Seq<Throwable>. I think, there is no parameter inference possible that makes sense for this example. Hence the compiler rightly rejects it.
I guess, obvious mistakes like this have long been fixed in the specification. Where is the most recent release of the spec? I could not find anything on Sun's website.
Re: Is there a final specification of Java generics?
Aug 2, 2003 10:53 AM
(reply 3
of 10) (In reply to
#2 )
There is new revision of the specification. It comes with the latest version of the prototype compiler (see http://developer.java.sun.com/developer/earlyAccess/adding_generics/index.html). But it's not the final specification, as far as I can tell.
Re: Is there a final specification of Java generics?
Aug 5, 2003 8:51 AM
(reply 5
of 10) (In reply to
#4 )
Be sure to see
http://cscott.net/Projects/GJ/#bugs
for more draft specification omissions/errors, and their corrections.
In particular, explicit type parameters on method and constructor invocation are specified incorrectly.
Re: Is there a final specification of Java generics?
Aug 5, 2003 10:06 AM
(reply 6
of 10) (In reply to
#3 )
The erroneous example in the first post of this thread is still present (and still incorrect) in the latest version of the spec. Although it still compiles, the inferred types specified by the spec are all wrong: Seq<Object> is inferred for every example. For example, if you modify the Seq<Throwable> example slightly:
Re: Is there a final specification of Java generics?
Aug 5, 2003 1:45 PM
(reply 7
of 10) (In reply to
#5 )
In particular, explicit type parameters on method and
constructor invocation are specified incorrectly.
You mean, the syntax productions do allow wildcards as explicit type arguments, but the specification expressly says: "they are not allowed". Or is there anything else that is incorrectly specified regarding explicit type argument specification of methods?
By the way, does anybody know why wildcards are illegal as explicit type arguments of methods? Just because it would be yet another burden to the compiler in the method overloading, type inference, bounds checking process? Or is there another reason for this rule?
I'm not saying that wildcards as explicit type arguments are desperately needed. I'm just wondering ...
Re: Is there a final specification of Java generics?
Aug 6, 2003 12:15 PM
(reply 9
of 10) (In reply to
#7 )
You mean, the syntax productions do allow wildcards as
explicit type arguments, but the specification
expressly says: "they are not allowed". Or is there
anything else that is incorrectly specified regarding
explicit type argument specification of methods?
No, the placement of the type arguments production is incorrect. Please compare the grammars; that's the most precise way to specify the differences.
Re: Is there a final specification of Java generics?
Aug 7, 2003 10:52 AM
(reply 10
of 10) (In reply to
#9 )
Just to be more helpful, my corrected grammar for MethodInvocation is:
MethodInvocation ::= MethodExpr ( ArgumentListOpt )
MethodExpr ::= MethodName
| Primary . TypeArgumentsOpt Identifier
| super . TypeArgumentsOpt Identifier
| Name . super . TypeArgumentsOpt Identifier
while the original grammar contained this production:
MethodExpr ::= TypeArgumentsOpt MethodName
| ...
Type arguments in front of an unqualified method name can't be unambiguously parsed, so they have been made illegal. You need to use a primary (a class expression for non-static methods or a class name for static methods) to resolve the ambiguity.
Similarly, the corrected constructor invocation productions are:
ClassInstanceCreationExpression ::= new TypeArgumentsOpt
ClassOrInterfaceType ( ArgumentListOpt ) ClassBodyOpt
| Primary . new TypeArgumentsOpt
Identifier TypeArgumentsOpt ( ArgumentListOpt ) ClassBodyOpt
while the original was:
ClassInstanceCreationExpression ::= TypeArgumentsOpt new
ClassOrInterfaceType TypeArgumentsOpt
( ArgumentListOpt ) ClassBodyOpt
| Primary.TypeArgumentsOpt new
Identifier TypeArgumentsOpt
( ArgumentListOpt ) ClassBodyOpt
here the placement of the TypeArguments productions had to be moved in order to resolve grammar ambiguities; in addition "ClassOrInterfaceType" already includes an optional final TypeArguments clause, and so the extra one in the first alternative needed to be removed.