On 4/12/26 13:59, Paul King wrote:
Hi folks,

We have been asked numerous times about the possibility of having a "val" keyword to match Kotlin and Scala. We also have had a related Jira open for more than 6 years. So I created a GEP to help frame a discussion about what would be involved and help us make a decision:

https://groovy.apache.org/wiki/GEP-16.html <https://groovy.apache.org/ wiki/GEP-16.html>

I know we have "final", but many developers I speak to from the Kotlin and Scala worlds are big fans of "val" and believe it was the right name to use for those two languages.

Given that it involves changes to only about 15 lines of production Groovy code and has well-identified impacts (arguably edge cases with workarounds), I am largely in favor of this proposal, but I am keen to hear other's thoughts.

I must say I agree a lot with OC and mg. I do not see the value of val, if it is just an alias for final. And there is the breaking code issue. Remember that we have def that kinda works like an alias for Object, which already did confuse many people in the past.

But there is also the usage in bodies and the usage for declaring properties and fields. (also partially mentioned, just want to extend on that discussion)

a) method body

final foo = new Foo()
foo.bar = 10

Dynamic Groovy will issue a variable with static type Object which gets a Foo assigned. foo.bar can be used since the runtime type is Foo and the static type plays no role here. Static Groovy should also issue a variable with static type Object afaik. foo.bar works here because the compiler knows by flow typing that foo is actually a Foo and casts foo to a Foo. But since foo will not change it is legal to just give foo here the type Foo instead of Object and save on the casts. Which is what static Groovy does.


b) property/field
class Foo {
  final bar = new Bar()
}

Here again dynamic Groovy will use Object and so will static Groovy, since formally the type of bar is Object. It is kind of a special case since

class Foo {
  final bar
  {
    bar = new Bar()
  }
}

is not evaluated in Groovy like in Java when it comes to type information. In fact, Groovy also accepts this

@CompileStatic
class Foo {
  final bar
  {bar = new Bar()}
  {bar = new Bar()}
}

which should fail compilation since we assign twice to the field bar.

Anyway, point is the property/field type is Object, which may not be what you desire.

bye Jochen

Reply via email to