You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@groovy.apache.org by Paul King <pa...@asert.com.au> on 2021/09/21 07:40:38 UTC

[DISCUSS] Some potential additional system properties/CompilerConfiguration flags for Groovy 4

Hi folks,

[A bit of a long winded explanation but hopefully you will bear with me.]

For recent features like sealed classes and records*, we are moving towards
implementations which support the feature natively (as per Java) when
compiled with a suitable target bytecode version, and fall back to some
alternate mechanism on older JDK versions. E.g. native sealed classes vs
a @Sealed annotation. For sealed classes there are flags
in CompilerConfiguration (and corresponding system properties) to give
better control, e.g. do you still want the annotations even on a native
sealed class. Feedback on the existing implementation is as always welcome
but that is distinct from what I am asking here.

Do folks think an additional flag would be useful that failed compilation
if the native option wasn't enabled?

Here is an example to spell out the idea. The idea is that if I have:

sealed class Shape { ... }
final class Triangle extends Shape { ... }
...

And then, if I compile with target bytecode at JDK17 I will get a sealed
class (for Shape) as expected in the Java world but just one annotated
with @Sealed if I use for instance JDK8. The target version is detected and
used to switch between the two potential outcomes with already some flags
to control the behavior a little. I wonder whether folks familiar with Java
will be surprised that they use the `sealed` keyword but don't really get a
sealed class and they are hoping to use the class as is with Java.

It seems we have three options:
(1) Leave as is. Our documentation explains the fallback scenarios, so
users should familiarise themselves with it!
(2) Provide an additional system property/flag/CompilerConfig setting which
users could turn on and if the target bytecode version doesn't meet the
required level for native support it would fail. The flag would be opt in,
i.e. our existing best implementation based on version is the default but
the flag would give a stricter option. With the flag set, if you compile my
"sealed class" code on an old JDK it won't compile since I really meant to
get a sealed class.
(3) Leave this up to the next gen of CodeNarc Groovy 4 rules (not sure we
have ever had version specific ones like this before).

This example is around sealed classes but there will be similar concerns
for records. Thoughts?

* PR pending

Cheers, Paul.

Re: [EXT] Re: [DISCUSS] Some potential additional system properties/CompilerConfiguration flags for Groovy 4

Posted by Christopher Smith <ch...@gmail.com>.
I will concur in part and disagree in part with Eric: I think that as a
broad rule it makes sense to baseline, but on JDK LTS releases, which it
happens 17 is.

That said, 17 seems likely to finally introduce serious breaking changes
that have been warned about for a decade, and I absolutely predict a
plateau as happened on 8 after 9 was released, so *if* it is easy enough to
polyfill sealed classes, it might make sense. (I am unsure of the
difference between records and @Immutable except that records are shallowly
immutable.)

If it is practical to backport sealedy behavior (just make all of the leaf
classes final?), that would be useful.

On Wed, Sep 22, 2021, 10:21 Milles, Eric (TR Technology) <
eric.milles@thomsonreuters.com> wrote:

> I am not in favor of more system properties to switch behavior all
> around.  If sealed classes are of interest, then a Java 17 JVM is a
> reasonable requirement.  I think this can be applied to records, switch
> expressions, etc.  To keep it simple, require the minimum Java version that
> supports a feature natively.  Releases are coming so fast now (every six
> months) that trying to backport this kind of thing to Java 11 or 8 seems
> less beneficial than it was a few years back.
>
>
>
> *From:* Mario Garcia <ma...@gmail.com>
> *Sent:* Tuesday, September 21, 2021 3:10 AM
> *To:* dev@groovy.apache.org; Paul King <pa...@asert.com.au>
> *Subject:* [EXT] Re: [DISCUSS] Some potential additional system
> properties/CompilerConfiguration flags for Groovy 4
>
>
>
> *External Email:* Use caution with links and attachments.
>
>
>
> Hi:
>
>
>
> Here are my thoughts. Maybe I'm wrong but, if somebody is familiar with
> JDK17 sealed classes, I don't think that person would expect that using
> sealed syntax with JDK8 is going to output a JDK17 sealed class. I would
> add it to the documentation and that's it.
>
>
>
> To me seems that implementing such scenario of compiler configuration is
> going to be done for the sake of part of the 1/3 of the potential users:
>
>    - I would like to use sealed-classes -> use JDK17
>    - I love Groovy and I'd like to use sealed classes -> Use Groovy 4 and
>    JDK 17
>    - I love Groovy but I'm stuck in JDK8 OR I love Java and I'd like to
>    use sealed classes but again stuck in JDK8 -> Use Groovy 4 and be aware
>    that, although it looks like sealed classes, you're not using JDK17,
>    so it won't be the JDK17 sealed class
>
> Anyway, I would wait until this is really a real concern rather than a
> premature optimization and I would use that time and effort in other parts
> of the language. You already mentioned it, I also think Codenarc could be a
> good fit for this.
>
>
>
> My two cents
>
>
>
> El mar, 21 sept 2021 a las 9:41, Paul King (<pa...@asert.com.au>)
> escribió:
>
>
>
> Hi folks,
>
>
>
> [A bit of a long winded explanation but hopefully you will bear with me.]
>
>
>
> For recent features like sealed classes and records*, we are moving
> towards implementations which support the feature natively (as per Java)
> when compiled with a suitable target bytecode version, and fall back to
> some alternate mechanism on older JDK versions. E.g. native sealed classes
> vs a @Sealed annotation. For sealed classes there are flags
> in CompilerConfiguration (and corresponding system properties) to give
> better control, e.g. do you still want the annotations even on a native
> sealed class. Feedback on the existing implementation is as always welcome
> but that is distinct from what I am asking here.
>
>
>
> Do folks think an additional flag would be useful that failed compilation
> if the native option wasn't enabled?
>
>
>
> Here is an example to spell out the idea. The idea is that if I have:
>
> sealed class Shape { ... }
> final class Triangle extends Shape { ... }
> ...
>
> And then, if I compile with target bytecode at JDK17 I will get a sealed
> class (for Shape) as expected in the Java world but just one annotated
> with @Sealed if I use for instance JDK8. The target version is detected and
> used to switch between the two potential outcomes with already some flags
> to control the behavior a little. I wonder whether folks familiar with Java
> will be surprised that they use the `sealed` keyword but don't really get a
> sealed class and they are hoping to use the class as is with Java.
>
>
>
> It seems we have three options:
> (1) Leave as is. Our documentation explains the fallback scenarios, so
> users should familiarise themselves with it!
>
> (2) Provide an additional system property/flag/CompilerConfig setting
> which users could turn on and if the target bytecode version doesn't meet
> the required level for native support it would fail. The flag would be opt
> in, i.e. our existing best implementation based on version is the default
> but the flag would give a stricter option. With the flag set, if you
> compile my "sealed class" code on an old JDK it won't compile since I
> really meant to get a sealed class.
>
> (3) Leave this up to the next gen of CodeNarc Groovy 4 rules (not sure we
> have ever had version specific ones like this before).
>
>
>
> This example is around sealed classes but there will be similar concerns
> for records. Thoughts?
>
>
>
> * PR pending
>
>
>
> Cheers, Paul.
>
>
>
>

RE: [EXT] Re: [DISCUSS] Some potential additional system properties/CompilerConfiguration flags for Groovy 4

Posted by "Milles, Eric (TR Technology)" <er...@thomsonreuters.com>.
I am not in favor of more system properties to switch behavior all around.  If sealed classes are of interest, then a Java 17 JVM is a reasonable requirement.  I think this can be applied to records, switch expressions, etc.  To keep it simple, require the minimum Java version that supports a feature natively.  Releases are coming so fast now (every six months) that trying to backport this kind of thing to Java 11 or 8 seems less beneficial than it was a few years back.

From: Mario Garcia <ma...@gmail.com>
Sent: Tuesday, September 21, 2021 3:10 AM
To: dev@groovy.apache.org; Paul King <pa...@asert.com.au>
Subject: [EXT] Re: [DISCUSS] Some potential additional system properties/CompilerConfiguration flags for Groovy 4

External Email: Use caution with links and attachments.

Hi:

Here are my thoughts. Maybe I'm wrong but, if somebody is familiar with JDK17 sealed classes, I don't think that person would expect that using sealed syntax with JDK8 is going to output a JDK17 sealed class. I would add it to the documentation and that's it.

To me seems that implementing such scenario of compiler configuration is going to be done for the sake of part of the 1/3 of the potential users:

  *   I would like to use sealed-classes -> use JDK17
  *   I love Groovy and I'd like to use sealed classes -> Use Groovy 4 and JDK 17
  *   I love Groovy but I'm stuck in JDK8 OR I love Java and I'd like to use sealed classes but again stuck in JDK8 -> Use Groovy 4 and be aware that, although it looks like sealed classes, you're not using JDK17, so it won't be the JDK17 sealed class
Anyway, I would wait until this is really a real concern rather than a premature optimization and I would use that time and effort in other parts of the language. You already mentioned it, I also think Codenarc could be a good fit for this.

My two cents

El mar, 21 sept 2021 a las 9:41, Paul King (<pa...@asert.com.au>>) escribió:

Hi folks,

[A bit of a long winded explanation but hopefully you will bear with me.]

For recent features like sealed classes and records*, we are moving towards implementations which support the feature natively (as per Java) when compiled with a suitable target bytecode version, and fall back to some alternate mechanism on older JDK versions. E.g. native sealed classes vs a @Sealed annotation. For sealed classes there are flags in CompilerConfiguration (and corresponding system properties) to give better control, e.g. do you still want the annotations even on a native sealed class. Feedback on the existing implementation is as always welcome but that is distinct from what I am asking here.

Do folks think an additional flag would be useful that failed compilation if the native option wasn't enabled?

Here is an example to spell out the idea. The idea is that if I have:

sealed class Shape { ... }
final class Triangle extends Shape { ... }
...

And then, if I compile with target bytecode at JDK17 I will get a sealed class (for Shape) as expected in the Java world but just one annotated with @Sealed if I use for instance JDK8. The target version is detected and used to switch between the two potential outcomes with already some flags to control the behavior a little. I wonder whether folks familiar with Java will be surprised that they use the `sealed` keyword but don't really get a sealed class and they are hoping to use the class as is with Java.

It seems we have three options:
(1) Leave as is. Our documentation explains the fallback scenarios, so users should familiarise themselves with it!
(2) Provide an additional system property/flag/CompilerConfig setting which users could turn on and if the target bytecode version doesn't meet the required level for native support it would fail. The flag would be opt in, i.e. our existing best implementation based on version is the default but the flag would give a stricter option. With the flag set, if you compile my "sealed class" code on an old JDK it won't compile since I really meant to get a sealed class.
(3) Leave this up to the next gen of CodeNarc Groovy 4 rules (not sure we have ever had version specific ones like this before).

This example is around sealed classes but there will be similar concerns for records. Thoughts?

* PR pending

Cheers, Paul.


Re: [DISCUSS] Some potential additional system properties/CompilerConfiguration flags for Groovy 4

Posted by Mario Garcia <ma...@gmail.com>.
Hi:

Here are my thoughts. Maybe I'm wrong but, if somebody is familiar with
JDK17 sealed classes, I don't think that person would expect that using
sealed syntax with JDK8 is going to output a JDK17 sealed class. I would
add it to the documentation and that's it.

To me seems that implementing such scenario of compiler configuration is
going to be done for the sake of part of the 1/3 of the potential users:

   - I would like to use sealed-classes -> use JDK17
   - I love Groovy and I'd like to use sealed classes -> Use Groovy 4 and
   JDK 17
   - I love Groovy but I'm stuck in JDK8 OR I love Java and I'd like to use
   sealed classes but again stuck in JDK8 -> Use Groovy 4 and be aware that,
   although it looks like sealed classes, you're not using JDK17, so it
   won't be the JDK17 sealed class

Anyway, I would wait until this is really a real concern rather than a
premature optimization and I would use that time and effort in other parts
of the language. You already mentioned it, I also think Codenarc could be a
good fit for this.

My two cents

El mar, 21 sept 2021 a las 9:41, Paul King (<pa...@asert.com.au>) escribió:

>
> Hi folks,
>
> [A bit of a long winded explanation but hopefully you will bear with me.]
>
> For recent features like sealed classes and records*, we are moving
> towards implementations which support the feature natively (as per Java)
> when compiled with a suitable target bytecode version, and fall back to
> some alternate mechanism on older JDK versions. E.g. native sealed classes
> vs a @Sealed annotation. For sealed classes there are flags
> in CompilerConfiguration (and corresponding system properties) to give
> better control, e.g. do you still want the annotations even on a native
> sealed class. Feedback on the existing implementation is as always welcome
> but that is distinct from what I am asking here.
>
> Do folks think an additional flag would be useful that failed compilation
> if the native option wasn't enabled?
>
> Here is an example to spell out the idea. The idea is that if I have:
>
> sealed class Shape { ... }
> final class Triangle extends Shape { ... }
> ...
>
> And then, if I compile with target bytecode at JDK17 I will get a sealed
> class (for Shape) as expected in the Java world but just one annotated
> with @Sealed if I use for instance JDK8. The target version is detected and
> used to switch between the two potential outcomes with already some flags
> to control the behavior a little. I wonder whether folks familiar with Java
> will be surprised that they use the `sealed` keyword but don't really get a
> sealed class and they are hoping to use the class as is with Java.
>
> It seems we have three options:
> (1) Leave as is. Our documentation explains the fallback scenarios, so
> users should familiarise themselves with it!
> (2) Provide an additional system property/flag/CompilerConfig setting
> which users could turn on and if the target bytecode version doesn't meet
> the required level for native support it would fail. The flag would be opt
> in, i.e. our existing best implementation based on version is the default
> but the flag would give a stricter option. With the flag set, if you
> compile my "sealed class" code on an old JDK it won't compile since I
> really meant to get a sealed class.
> (3) Leave this up to the next gen of CodeNarc Groovy 4 rules (not sure we
> have ever had version specific ones like this before).
>
> This example is around sealed classes but there will be similar concerns
> for records. Thoughts?
>
> * PR pending
>
> Cheers, Paul.
>
>

Re: [DISCUSS] Some potential additional system properties/CompilerConfiguration flags for Groovy 4

Posted by MG <mg...@arscreat.com>.
What I meant by "actual sealed classes" is two things, both currently 
hypothetical, both related to least surprise:

 1. Sealed classes that also worked as expected when you use them
    through a Java framework combined with Groovy (evidently not
    possible for JDK < 17).
 2. Whether Groovy @Sealed is planned to support all (future) features
    with regards to exhaustiveness etc the Java side is talking about
    for JDK < 17 ?

I am not a big fan of sealed/private concepts in general, so this is not 
an important topic for me. In the end not many things are as immutable 
as a developer might think when designing a sealed hierarchy  
(languages, currencies, planets in our solar system, states of matter, 
...), which then creates the need for a forced major version upgrade, 
since no other workaround is possible, due to the sealed nature of the 
implementation. On the other hand the benefits of exhaustiveness, while 
theoretically intriguing, are imho limited in practice, since errors of 
this kind are in my experience a) easy to catch with tests, b) otherwise 
pop up quickly & are trivial to pinpoint and c) are easily fixed.

I agree with your conclusion not to invest any effort here for now,
mg



On 23/09/2021 22:38, Paul King wrote:
>
> Some replies inline.
>
> On Fri, Sep 24, 2021 at 6:03 AM MG <mgbiz@arscreat.com 
> <ma...@arscreat.com>> wrote:
>
>     Hi Paul,
>
>     I know you do not like them, but that again sounds like a perfect
>     example for an e.g. "WARNING: Use of sealed keyword with JDK < 17
>     leads
>     to @Sealed emulation behavior instead." or something along that line.
>
>
> It isn't so much whether I like them or not. It is just an historical
> point to note that the current compiler design and approach has
> been to avoid using them. So adding them in is non-trivial.
>
>     (Warnings have the advantage that one can turn them off through a
>     standard mechanism, but can easily turn all back on again, to see
>     what
>     Groovy is warning about, contrary to a switch which one has to know
>     about and which aborts at some point during compilation, not
>     showing all
>     problems that will in the end be found.)
>
>     If I understand this correctly, a flag would only make sense to me
>     if it
>     is set by default, because then Groovy compilation would always
>     initially fail in the JDK < 17 case, alerting people to the fact that
>     their class is not really sealed. I cannot see someone educating
>     himself
>     about the existence of the flag beforehand, but not knowing about the
>     fact that actual sealed classes require JDK 17.
>
>
> It depends on what you mean by "actual sealed classes".
> As a Groovy user, sealed classes would always work by one of two
> mechanisms - one being the @Sealed annotation. Which mechanism
> is in play is totally transparent and is handled by the Groovy compiler.
> If I care also about Java integration, then only the native sealed
> mechanism would be known by a Java compiler.
> The proposed switch was something which folks who care about
> Java integration would need to educate themselves about.
>
> My take on the feedback is to keep it simple, so I won't implement
> for now. We can always add later if it proves of great interest and
> can't be handled by other means.
>
>     Cheers,
>     mg
>
>
>
>     On 21/09/2021 09:40, Paul King wrote:
>     > For recent features like sealed classes and records*, we are moving
>     > towards implementations which support the feature natively (as per
>     > Java) when compiled with a suitable target bytecode version, and
>     fall
>     > back to some alternate mechanism on older JDK versions. E.g. native
>     > sealed classes vs a @Sealed annotation. For sealed classes there
>     are
>     > flags in CompilerConfiguration (and corresponding system
>     properties)
>     > to give better control, e.g. do you still want the annotations
>     even on
>     > a native sealed class. Feedback on the existing implementation
>     is as
>     > always welcome but that is distinct from what I am asking here.
>     >
>     > Do folks think an additional flag would be useful that failed
>     > compilation if the native option wasn't enabled?
>
>


Re: [DISCUSS] Some potential additional system properties/CompilerConfiguration flags for Groovy 4

Posted by Paul King <pa...@asert.com.au>.
Some replies inline.

On Fri, Sep 24, 2021 at 6:03 AM MG <mg...@arscreat.com> wrote:

> Hi Paul,
>
> I know you do not like them, but that again sounds like a perfect
> example for an e.g. "WARNING: Use of sealed keyword with JDK < 17 leads
> to @Sealed emulation behavior instead." or something along that line.
>

It isn't so much whether I like them or not. It is just an historical
point to note that the current compiler design and approach has
been to avoid using them. So adding them in is non-trivial.


> (Warnings have the advantage that one can turn them off through a
> standard mechanism, but can easily turn all back on again, to see what
> Groovy is warning about, contrary to a switch which one has to know
> about and which aborts at some point during compilation, not showing all
> problems that will in the end be found.)
>
> If I understand this correctly, a flag would only make sense to me if it
> is set by default, because then Groovy compilation would always
> initially fail in the JDK < 17 case, alerting people to the fact that
> their class is not really sealed. I cannot see someone educating himself
> about the existence of the flag beforehand, but not knowing about the
> fact that actual sealed classes require JDK 17.
>

It depends on what you mean by "actual sealed classes".
As a Groovy user, sealed classes would always work by one of two
mechanisms - one being the @Sealed annotation. Which mechanism
is in play is totally transparent and is handled by the Groovy compiler.
If I care also about Java integration, then only the native sealed
mechanism would be known by a Java compiler.
The proposed switch was something which folks who care about
Java integration would need to educate themselves about.

My take on the feedback is to keep it simple, so I won't implement
for now. We can always add later if it proves of great interest and
can't be handled by other means.



> Cheers,
> mg
>
>
>
> On 21/09/2021 09:40, Paul King wrote:
> > For recent features like sealed classes and records*, we are moving
> > towards implementations which support the feature natively (as per
> > Java) when compiled with a suitable target bytecode version, and fall
> > back to some alternate mechanism on older JDK versions. E.g. native
> > sealed classes vs a @Sealed annotation. For sealed classes there are
> > flags in CompilerConfiguration (and corresponding system properties)
> > to give better control, e.g. do you still want the annotations even on
> > a native sealed class. Feedback on the existing implementation is as
> > always welcome but that is distinct from what I am asking here.
> >
> > Do folks think an additional flag would be useful that failed
> > compilation if the native option wasn't enabled?
>
>
>

Re: [DISCUSS] Some potential additional system properties/CompilerConfiguration flags for Groovy 4

Posted by MG <mg...@arscreat.com>.
Hi Paul,

I know you do not like them, but that again sounds like a perfect 
example for an e.g. "WARNING: Use of sealed keyword with JDK < 17 leads 
to @Sealed emulation behavior instead." or something along that line.
(Warnings have the advantage that one can turn them off through a 
standard mechanism, but can easily turn all back on again, to see what 
Groovy is warning about, contrary to a switch which one has to know 
about and which aborts at some point during compilation, not showing all 
problems that will in the end be found.)

If I understand this correctly, a flag would only make sense to me if it 
is set by default, because then Groovy compilation would always  
initially fail in the JDK < 17 case, alerting people to the fact that 
their class is not really sealed. I cannot see someone educating himself 
about the existence of the flag beforehand, but not knowing about the 
fact that actual sealed classes require JDK 17.

Cheers,
mg



On 21/09/2021 09:40, Paul King wrote:
> For recent features like sealed classes and records*, we are moving 
> towards implementations which support the feature natively (as per 
> Java) when compiled with a suitable target bytecode version, and fall 
> back to some alternate mechanism on older JDK versions. E.g. native 
> sealed classes vs a @Sealed annotation. For sealed classes there are 
> flags in CompilerConfiguration (and corresponding system properties) 
> to give better control, e.g. do you still want the annotations even on 
> a native sealed class. Feedback on the existing implementation is as 
> always welcome but that is distinct from what I am asking here.
>
> Do folks think an additional flag would be useful that failed 
> compilation if the native option wasn't enabled?