PROPOSAL: language support for JSR 292

Rémi Forax forax at univ-mlv.fr
Thu Apr 30 12:07:50 PDT 2009


The first question is what is the goal of such construct.

If the goal is to be able to call any dynamic languages from Java,
this is in my opinion a nice dream but that means
mixing different language semantics.

If the goal is to help dynamic language developers,
the question is why a language developer code in Java
and not in its own language.

If the goal is to simplify reflection or dynamic invocation
in Java, the dynamic type of C# is what we want.

Rémi

Maurizio Cimadamore a écrit :
> John Rose wrote:
>   
>> On Apr 3, 2009, at 1:25 AM, Joseph D. Darcy wrote:
>>
>>   
>>     
>>> Reiterating a point Neal raised, if Dynamic is not related to Object,
>>> what does that mean when Dynamic is used as the format type argument  
>>> to
>>> a type parameter?  What do "? extends Dynamic" and "? super Dynamic"
>>> mean to the type system?
>>>     
>>>       
>> It means something limited like ? extends String or ? super Object.   
>> I.e., there aren't any interesting types other than Dynamic itself  
>> that match the wildcard.
>>
>>   
>>     
> 1) I'd strongly recommend to forbid usage of InvokeDynamic type in the 
> following contexts:
>
> (i) extends clause (e.g. class MyDynamic extends InvokeDynamic)
> (ii) type-parameter bound (e.g. class Foo<X extends InvokeDynamic & 
> Comparable<?>>)
> (iii) wildcard type-argument (e.g. Foo<? extends InvokeDynamic)
>
> While generics/wildcards are essentially a way to refine static 
> type-checking, InvokeDynamic provides a way to disable static checking 
> completely. For this reason I don't see the two features going side by 
> side in any meaningful way. It is true that now that InvokeDynamic has 
> become an abstract holder of static methods, it probably makes less 
> sense to write code like the above (apart from (i) which users might be 
> tempted to write) - nevertheless the compiler should detect such invalid 
> usages and flag them as errors.
>
> My point is that a Java class shouldn't ever need to be parameterized on 
> something that is bound by InvokeDynamic (or Dynamic) - as those types 
> do not provide the type-system with any info.
>
> 2) I agree with Neal that the usage of Void feels a bit hacky. If you 
> need null values to be typed differently then I agree that probably 
> adding java.lang.Null would be the best thing to do, rather than 
> overriding the semantics of Void.
>
> 3) InvokeDynamic and type-inference. It seems like you can optionally 
> provide a type-parameter denoting the dynamic call's expected return 
> type. This is fine, as long as it is consistent with JLS 15.12.2.7 and 
> 15.12.2.8. In your examples it seems like the usage of such type 
> argument is completely optional. If specified, it provides additional 
> info about the dynamic call site such that, e.g. the following code will 
> be rejected:
>
> int i = InvokeDynamic.<String>myDynMethod("Hello!"); // type (String) -> 
> String
>
> Can this optional type argument be inferred so that the following method 
> call will behave identically?
>
> int i = InvokeDynamic.myDynMethod("Hello!"); // type (String) -> String
>
> [I did some testing and it seems like inference is not supported - the 
> above line will give an incompatible types error, found Object, expecetd 
> int]
>
> If so, you are mimicking an under-constrained type-variable (a method 
> type variable that cannot be inferred from actual arguments passed to 
> the method). This raises a question: what happens when the dynamic call 
> site does not appear within an assignment context, e.g.
>
> InvokeDynamic.myDynMethod("Hello!");
>
> or
>
> int i = (Integer)InvokeDynamic.myDynMethod("Hello!");
>
> In those cases, following 15.12.2.8, the under-constrained type variable 
> should be inferred to be its declared bound. What does it mean in this 
> case? Object ? Null ? Reading from your examples it seems like if no 
> optional type-argument for the return type is provided, no info about 
> the return type is included in the MethodHandle type generated by javac. 
> Which means that this behavior cannot be explained in terms of generic 
> method call/type inference (and thus 15.12.2.7/15.12.2.8).
>
> An alternative would be to pass to InvokeDynamic the return type Class 
> object corresponding the to expected return type as the first parameter 
> of the dynamic call:
>
> InvokeDynamic.myDynMethod(int.class, "Hello!"); // type (String) -> int
>
> This has the advantage of not requiring a separate language extension in 
> order to allow primitive type (and void) to be specified as parameter types.
>
> Maurizio
>   
>>> Actually there is a special rule that catching Exception is always  
>>> okay
>>> per JLS 11.2.3; this program is legal and compiles fine:
>>>
>>> public class Test {
>>>    public static void main(String... args){
>>>    try {
>>>        ;
>>>    } catch (Exception e) {
>>>        ;
>>>    }
>>>    }
>>> }
>>>
>>>     
>>>       
>> Thanks.  Amending the example to IOError.
>>
>>   
>>     
>>> So what are the notions of identity and equality for method handles?
>>>     
>>>       
>> Inherited from Object. Nothing special.
>>
>>   
>>     
>>> [snip]
>>>     
>>>       
>>>> 4.1 As specified above, the interface java.dyn.Dynamic has no
>>>> supertypes or members.  As such, it is a bare reference type.  (As an
>>>> arbitrary relation, the superclass of Dynamic[] is Object[].)  We
>>>>
>>>>       
>>>>         
>>> Are there any other type building operations besides arrays we need to
>>> worry about?
>>>     
>>>       
>> I don't think so.
>>
>> List<Dynamic> is impossible for interesting reasons.  The (erased)  
>> implementation of List internally makes use of Object.toString,  
>> Object.equals, and perhaps other such methods.  These calls are wrong  
>> for Dynamic values, since Dynamic (not being a subtype) does not  
>> inherit Object.equals and the rest.  This allows a Dynamic object to  
>> cleanly model another language, without holes in its method namespace.
>>
>> (Consider a process-oriented capability for which the name "wait" is  
>> significant, or some knowledge representation language that has  
>> different notions about "equals".  The MOP doesn't need to special- 
>> case those names.  It's a small point but worth defending, I think.)
>>
>> (In C#, with reified types, they can customize their List<Dynamic> to  
>> make a MOP-mediated call to equals, I suppose.)
>>
>>   
>>     
>>>> But, the Java operators "==" "!=" "+" "+=" on reference types are
>>>> clarified to apply only to reference types which are java.lang.Object
>>>> or one of its subtypes; they do not have a predefined meaning if
>>>> either operand is dynamic.  The "synchronized" and "throw" statements
>>>> cannot be applied to dynamic expressions.
>>>>
>>>>       
>>>>         
>>> So if there is no predefined meaning, are those operations illegal?
>>>     
>>>       
>> Yes.  More specifically, they are reserved for future use, in case we  
>> want to do something with dynamic operator overloading.
>>
>> (There's a half-baked sketch of what this could mean someday, on the  
>> mlvm wiki.  It's not ready to discuss yet.)
>>
>>   
>>     
>>>> Facilities which compute type relations (such as
>>>> javax.lang.model.util.Types) may need to be updated to take Dynamic
>>>> into account.  Generally speaking, the new Dynamic conversions  
>>>> operate
>>>> in parallel to the implicit boxing conversions.  That is, they add no
>>>> new subtype or supertype relations, but they provide a few more ways
>>>> for values to be implicitly converted or casted.
>>>>
>>>>       
>>>>         
>>> Yes, I would expect a few changes to the type-related APIs.  They may
>>> also need to be changes to programs that assume Object is the root of
>>> the reference type hierarchy.  I know I've written annotation  
>>> processing
>>> code like that and Dynamic would need to be special cased in there.
>>>     
>>>       
>> Thanks.
>>
>> As noted in the previous message, I have updated the proposal.
>>
>> -- John
>>
>>   
>>     
>
>
>   




More information about the coin-dev mailing list