Re: Record and annotation values

2018-04-09 Thread Brian Goetz



I agree, i do not think it's a good idea to introduce record as annotation 
value just because we can but that's not the reason why i think we should 
introduce record as annotation value.

There is a lot of time where you can construct an annotation with invalid 
values but those invalid annotation will not be catch at compile time but at 
runtime.
By example,
   @Test({ignore=false, timeout_value=-3, timeout_unit=SECOND})

So having a way to specify a contract for annotation values will make Java more 
safe.


This is why it is best to start with problems first, rather than 
solutions.  It was far from obvious that this was your underlying 
motivation, and given this motivation, its far from obvious this is the 
best way to get there.


So let's start over: the problem you're trying to solve is that there is 
not a good way currently to do compile- or run-time annotation validation?



yes, a specfic attribute is perhaps a better,
i wonder if the information in the RecordSignature should not be part of the 
Extractor.



I think the containment here is backwards.  An extractor is a 
lower-level mechanism for implementing conditional deconstruction, which 
includes pattern matching.  A class can have multiple extractors 
(patterns), just as it can have multiple constructors. Records have a 
distinguished extractor (the primary deconstructor pattern), just as 
they have a distinguished constructor.  It should be possible to 
reflectively navigate from a record class to its primary ctor/dtor.  
That might be by referring to them from the RecordSignature, or might be 
some other way (e.g., an invariant that you can use the record signature 
as an input to findConstructor / findDeconstructionPattern.)


Re: Record and annotation values

2018-04-08 Thread forax
- Mail original -
> De: "Brian Goetz" 
> À: "Remi Forax" , "amber-spec-experts" 
> 
> Envoyé: Dimanche 8 Avril 2018 23:33:33
> Objet: Re: Record and annotation values

> I think this is one in the category of "just because you can, doesn't
> meant you should."  So before discussing mechanisms, let's discuss goals.
> 
> Annotations are for metaDATA.  The restriction on what you can put in an
> annotation stems in part from what you can put in the constant pool, but
> busting the constant pool limits doesn't automatically mean its a good
> idea to make it an annotation value.
> 
> The rule that I've been gravitating towards is: anything that is
> important enough to have a _literal form_ in the language, probably is
> is a good candidate to consider as an annotation value.  The obvious
> first candidate is method refs (excluding instance-bound ones).  But
> even with mrefs in, I'd say no to lambdas, because annotation values
> should also be scrutable to annotation processors.  (If we had
> collection literals, then collections of things that can already go in
> annos is probably also a valid candidate.)
> 
> Don't forget that just because a record has all-final fields, doesn't
> mean its immutable all the way down.  And while some notion of
> "immutable all the way down" has been a frequent wish-list item, taking
> that on just so you can stash records in annotations is definitely tail
> wagging the dog.
> 

I agree, i do not think it's a good idea to introduce record as annotation 
value just because we can but that's not the reason why i think we should 
introduce record as annotation value.

There is a lot of time where you can construct an annotation with invalid 
values but those invalid annotation will not be catch at compile time but at 
runtime.
By example,  
  @Test({ignore=false, timeout_value=-3, timeout_unit=SECOND})

So having a way to specify a contract for annotation values will make Java more 
safe.

> 
> On the second point (reifying parameter names), while I don't object to
> doing this, this can't be the "official" way to get this data.  It
> should be reflectively accessible, because you need to nominally tie the
> constructor arguments to some way of getting their values (getters or
> fields).  The compiler prototype uses an annotation on the class
> declaration that stashes this, but that's just a prototyping hack; this
> probably needs a RecordSignature attribute.

yes, a specfic attribute is perhaps a better,
i wonder if the information in the RecordSignature should not be part of the 
Extractor.

Rémi

> 
> 
> On 4/8/2018 4:16 PM, Remi Forax wrote:
>> Currently annotation values are limited to what is encodable as a constant in
>> the constant pool.
>> With Condy, we can expand the number of values that can be encodable as a
>> constant in the constant pool to the infinity by allowing a reference to any
>> non-mutable class to be encoded as an annotation values.
>>
>> For that we need to have a 'protocol' that
>> - encode an instance of a user defined non-mutable class as a condy by the
>> compiler.
>> - decode an instance of a user defined non-mutable class by the JDK runtime.
>>
>> Records with their constructors do not provide enough meta-information for 
>> that,
>> the parameter names of the constructors may not be available at runtime.
>>
>> So i think the constructors parameter names of a Record should be always
>> recorded (as with --parameters was specified for the constructors) to enable
>> non-mutable records to be annotation values.
>>
>> Rémi


Re: Record and annotation values

2018-04-08 Thread Brian Goetz
I think this is one in the category of "just because you can, doesn't 
meant you should."  So before discussing mechanisms, let's discuss goals.


Annotations are for metaDATA.  The restriction on what you can put in an 
annotation stems in part from what you can put in the constant pool, but 
busting the constant pool limits doesn't automatically mean its a good 
idea to make it an annotation value.


The rule that I've been gravitating towards is: anything that is 
important enough to have a _literal form_ in the language, probably is 
is a good candidate to consider as an annotation value.  The obvious 
first candidate is method refs (excluding instance-bound ones).  But 
even with mrefs in, I'd say no to lambdas, because annotation values 
should also be scrutable to annotation processors.  (If we had 
collection literals, then collections of things that can already go in 
annos is probably also a valid candidate.)


Don't forget that just because a record has all-final fields, doesn't 
mean its immutable all the way down.  And while some notion of 
"immutable all the way down" has been a frequent wish-list item, taking 
that on just so you can stash records in annotations is definitely tail 
wagging the dog.



On the second point (reifying parameter names), while I don't object to 
doing this, this can't be the "official" way to get this data.  It 
should be reflectively accessible, because you need to nominally tie the 
constructor arguments to some way of getting their values (getters or 
fields).  The compiler prototype uses an annotation on the class 
declaration that stashes this, but that's just a prototyping hack; this 
probably needs a RecordSignature attribute.



On 4/8/2018 4:16 PM, Remi Forax wrote:

Currently annotation values are limited to what is encodable as a constant in 
the constant pool.
With Condy, we can expand the number of values that can be encodable as a 
constant in the constant pool to the infinity by allowing a reference to any 
non-mutable class to be encoded as an annotation values.

For that we need to have a 'protocol' that
- encode an instance of a user defined non-mutable class as a condy by the 
compiler.
- decode an instance of a user defined non-mutable class by the JDK runtime.

Records with their constructors do not provide enough meta-information for 
that, the parameter names of the constructors may not be available at runtime.

So i think the constructors parameter names of a Record should be always 
recorded (as with --parameters was specified for the constructors) to enable 
non-mutable records to be annotation values.

Rémi