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