groovy-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Paul King <>
Subject Re: Making @Immutable a meta-annotation
Date Mon, 15 Jan 2018 13:08:22 GMT
Response below.

On Sun, Jan 14, 2018 at 6:11 AM, MG <> wrote:

> Hi Paul,
> now I get where you are coming from with @KnownImmutable. I agree with
> splitting the two concepts: Flexible & elegant :-)
> Transferring the parameter name knownImmutables (which exists inside the
> @Immutable context) to the annotation name KnownImmutable (which has no
> such context) still does not work for me, though.
> In addition having @Immutable = @KnownImmutable + @ImmutableBase violates
> the definition you give for @KnownImmutable, because either the class is
> "known to be immutable" = "immutable by implementation by the developer",
> or it becomes immutable through @ImmutableBase & Groovy...

Well that is perhaps an indication that it needs to be explained better
rather than necessarily a bad name. I'll try again. It just means that
someone (the compiler or the developer) knows that it is immutable. If that
marker interface is on the class there is no need to look further inside
the class, you can assume it is vouched for as immutable. Once
@ImmutableBase (or whatever name) processing has finished its checks, it
can then vouch for the class and puts the marker interface "rubber stamp"
on it.

> What do you think about:
> @IsImmutable
> @ImmutableContract
> @GuaranteedImmutable
> instead
> ?
> Thinking about this some more, still don't like @ImmutableBase. Sounds too
> much like a base class to me - and what would be the "base" functionality
> of being immutable ? Something either is immutable, or not (@ImmutableCore
> also fails in this regard ;-) ).
> So still would prefer @ImmutableOnly o.s. ..

@ImmutableOnly indicates that it is somehow immutable at that point - it
isn't really a finished immutable class until all the other related
transforms have done their thing. Perhaps it is useful to reiterate what it
does. It does a whole pile of validation (you can't have public fields, you
can't have certain annotation attributes on some of the other annotations
that wouldn't make sense for an immutable object, you can't have your own
constructors, it can't be applied on interfaces, it checks spelling of
property names referenced in annotation attributes) plus some preliminary
changes (makes class final, ensures properties have a final private backing
field and a getter but no setter, makes a copyWith constructor if needed).
These changes alone don't guarantee immutability. Would you prefer

> Cheers,
> mg
> -------- Urspr√ľngliche Nachricht --------
> Von: Paul King <> <>
> Datum: 13.01.18 13:17 (GMT+01:00)
> An: MG <> <>
> Betreff: Re: Making @Immutable a meta-annotation
> I should have explained the @KnownImmutable idea a bit more. I guess I was
> thinking about several possibilities for that in parallel. What I really
> think is the way to go though is to split out the two different aspects
> that I was trying to capture. One is triggering the AST transformation, the
> other is a runtime marker of immutability. With that in mind I'd suggest
> the following:
> @KnownImmutable will be a marker interface and nothing more. Any class
> having that annotation will be deemed immutable.
> E.g. if I write my own Address class and I know it's immutable I can mark
> it as such:
> @KnownImmutable
> class Address {
>   Address(String value) { this.value = value }
>   final String value
> }
> Now if I have:
> @Immutable
> class Person {
>   String name
>   Address address
> }
> Then the processing associated with @Immutable won't complain about a
> potentially mutable "Address" field.
> Then we can just leave @ImmutableBase (or similar) as the AST transform to
> kick off the initial processing needed for immutable classes.
> The @Immutable annotation collector would be replaced by the constructor
> annotations, ToString, EqualsAndHashcode and both ImmutableBase and
> KnownImmutable.
> The name KnownImmutable matches existing functionality. Two alternatives
> to annotating Address with KnownImmutable that already exist would be using
> the following annotation attributes on @Immutable:
> @Immutable(knownImmutableClasses=[Address]) or
> @Immutable(knownImmutables=[address]).
> Cheers, Paul.
> On Sat, Jan 13, 2018 at 1:43 PM, MG <> wrote:
>> Hi Paul,
>> I think the core of the problem is, that @Immutable as a meta-annotation
>> woud be better off being called something along the line of
>> @ImmutableCanonical (see: If you do no need the immutability, use
>> @Canonical), since it does not solely supply immutability support - then it
>> would be natural to call the actual core immutability annotation just
>> "Immutable".
>> That is probably off the table, since it would be a breaking change - so
>> we are stuck with the problem of naming the immutability annotation part
>> something else.
>> @ImmutableClass would imply to me that the "Class" part carries some
>> meaning, which I feel it does not, since
>> a) "Class" could be postfixed to any annotation name that applies to
>> classes
>> b) The meta-annotation should accordingly also be called "ImmutableClass"
>> Because of that I find postfixing "Immutable" with "Class" just
>> confusing. It also is not intuitive to me, which annotation does only
>> supply the core, and which supplies the extended (canonical)
>> functionality...
>> I do not understand where you are going with @KnownImmutable (known to
>> whom ?-) To me this seems less intuitive/more confusing than
>> @ImmutableClass...).
>> @ImmutableCore is similar to @ImmutableBase (because I intentionally
>> based it on it :-) ), but different in the sense that it imho expresses the
>> semantics of the annotation: Making the object purely immutable-only,
>> without any constructors, toString functionality, etc.
>> How about:
>> @ImmutableOnly
>> @PureImmutable
>> @ModificationProtected
>> @Locked
>> @Frozen
>> @Unchangeable
>> @Changeless
>> @InitOnly
>> @InitializeOnly
>> @Constant
>> @Const
>> @NonModifieable
>> @NonChangeable
>> ?
>> mg
>> On 12.01.2018 08:01, Paul King wrote:
>> @ImmutableCore is similar to @ImmutableBase - probably okay but I don't
>> think ideal. Another alternative would be @ImmutableInfo or have an
>> explicit marker interface with a different package, e.g.
>> groovy.transform.marker.Immutable but that might cause IDE completion
>> headaches. Perhaps @KnownImmutable as a straight marker interface might be
>> the way to go - then it could be used explicitly on manually created
>> immutable classes and avoid the need to use the
>> knownImmutableClasses/knownImmutables annotation attributes for that
>> case.
>> Cheers, Paul.
>> On Thu, Jan 11, 2018 at 9:34 PM, mg <> wrote:
>>> Hi Paul,
>>> great to make @Immutable more fine granular / flexible :-)
>>> what about
>>> @ImmutabilityChecked
>>> or
>>> @ImmutableCore
>>> instead of @ImmutableClass ?
>>> Cheers
>>> mg
>>> -------- Urspr√ľngliche Nachricht --------
>>> Von: Paul King <>
>>> Datum: 11.01.18 08:07 (GMT+01:00)
>>> An:
>>> Betreff: Making @Immutable a meta-annotation
>>> There has been discussion on and off about making @Immutable a
>>> meta-annotation (annotation collector) in much the same way as @Canonical
>>> was re-vamped. (This is for 2.5+).
>>> I have a preliminary PR which does this:
>>> Preliminary because it still needs a bit of refactoring to reduce some
>>> duplication of code that exists between the normal and immutable map and
>>> tuple constructors. I still need to do this but that can happen
>>> transparently behind the scenes as an implementation detail if we don't
>>> finish it straight away. As well as reducing duplication, the pending
>>> refactoring will enable things like the pre and post options for
>>> MapConstructor and TupleConstructor which aren't currently working.
>>> I am keen on any feedback at this point. In particular, while most of
>>> the functionality is pushed off into the collected annotations/transforms,
>>> I ended up with some left over checks which I kept in an annotation
>>> currently called @ImmutableClass. I tried various names for this class,
>>> e.g. @ImmutableBase and @ImmutableCheck but finally settled on
>>> @ImmutableClass since the annotation causes the preliminary checks to be
>>> performed but also acts as a marker interface for the MapConstructor and
>>> TupleConstructor transforms to do the alternate code needed for
>>> immutability and to indicate that a class is immutable when it might itself
>>> be a property of another immutable class. Let me know if you can think of a
>>> better name or have any other feedback.
>>> Cheers, Paul.

View raw message