Using `var` for fields or properties is less meaningful than using `var` as a type placeholder for methods. I can understand that the word "(var)iable" is semantically more specific than the word "(def)ine" but it is not that ugly or alien in method definitions if we think of `var` as a placeholder for 'Object' (like what is `def` today).
If we want Groovy to "just" accept and compile Java code we should accept `var` only for local variables. What I am proposing though is that we use `var` as "the new `def`" so if we want to write code "the Python-ish way" we use `def`, if we want to write code "the Java-ish way" we use `var`. Gianluca Sartori -- Cell. +39 388 1026822 On Thu, 21 Nov 2024 at 20:48, Jonathan Carter <jonathanccar...@gmail.com> wrote: > The Oracle docs on var > <https://docs.oracle.com/en/java/javase/17/language/local-variable-type-inference.html> > are helpful, here. Specifically, this part: > > var can be used for the following types of variables: > > > - > > Local variable declarations with initializers: > > - > > Enhanced for-loop indexes: > > - > > Index variables declared in traditional for loops: > > - > > try-with-resources variable: > > - > > Formal parameter declarations of implicitly typed lambda expressions: > A lambda expression whose formal parameters have inferred types is > implicitly > typed: > > - > > In JDK 11 and later, you can declare each formal parameter of an > implicitly typed lambda expression with the var identifier: > > > In short, `var` is purely a local variable placeholder in Java. > > Given that Java carefully limited var to work as a reserved type name, not > a keyword to avoid interfering with existing code that used var as a > variable name, I do think there's potential for semantic surprise with Java > if Groovy expands it out to be a synonym for def. The Groovy semantics > <https://groovy-lang.org/semantics.html> documentation that Gianluca > refers to doesn't really advertise using var for fields or properties > either, even if it does happen to work. Indeed, the warnings around how > type inference works (or doesn't) for fields > <https://groovy-lang.org/semantics.html#_variables_vs_fields_in_type_inference> > makes me question whether we would want it to. Imagine the case of a Java > developer seeing, "Oh, I can declare a field with var, assign its value > immediately, and get type inference!" only for that to fail. > > I suspect that saying "def and var are basically just Object" probably > isn't helpful in the documentation, and leads to this surprising case that > Gianluca has run into here. This is a subjective case, and what surprises > you depends a lot on your background, but my hunch on the "least > surprising" thing to do for most people would be to document that "var is > only for local variables, just like Java" and treat its validity for fields > as an undocumented, possibly even a deprecated behavior. The note from the > aforementioned doc is relevant: > > Why such a difference? The reason is *thread safety*. At compile time, we >> can’t make *any* guarantee about the type of a field. Any thread can >> access any field at any time and between the moment a field is assigned a >> variable of some type in a method and the time is used the line after, >> another thread may have changed the contents of the field. This is not the >> case for local variables: we know if they "escape" or not, so we can make >> sure that the type of a variable is constant (or not) over time. Note that >> even if a field is final, the JVM makes no guarantee about it, so the type >> checker doesn’t behave differently if a field is final or not. >> >> This is one of the reasons why we recommend to use *typed* fields. While >> using def for local variables is perfectly fine thanks to type >> inference, this is not the case for fields, which also belong to the public >> API of a class, hence the type is important. >> > > Groovy may be more liberal than Java, but it seems like we'd still want to > steer people away from assuming "type inference works everywhere! I'm > freeeeeeee!" > > Best, > > Jonny > > > On Thu, Nov 21, 2024 at 12:27 PM most m <ubermenc...@gmail.com> wrote: > >> @Steve Etchelecu >> >> Java's var is a purely local type placeholder to elide the well-known >> verbosity when declaring and initializing variables on the same line, e.g. >> so that instead of writing "VeryLongTypename variable = new VeryLongType >> name(...);", you could omit the variable's type declaration and leave it be >> inferred from the initializer expression. >> >> I don't think javac considers it valid anywhere except a >> declare-and-initialize statement and a foreach loop iterator declaration. >> >> On Thu, Nov 21, 2024, 20:17 Steve Etchelecu <steve.etchel...@gmail.com> >> wrote: >> >>> I thought Gianluca made an excellent argument and helps modernize the >>> language. Given Groovy’s symbiotic relationship with Java, it seems like >>> the guidance here should probably be to follow Java’s usage as that likely >>> keeps friction/confusion to a minimum. >>> >>> Not being a Java developer, it isn’t clear to me whether Java supports >>> var as a return type though I assume it does for consistency. >>> >>> On Nov 21, 2024, at 11:10, Milles, Eric (TR Technology) via dev < >>> dev@groovy.apache.org> wrote: >>> >>> >>> I don't think semantically that "var name() { ... }" makes sense. >>> >>> One might argue that var for field and property do not make sense >>> either. We could explore removing support for var on class members. >>> ------------------------------ >>> *From:* Gianluca Sartori <g.sart...@gmail.com> >>> *Sent:* Thursday, November 21, 2024 10:57 AM >>> *To:* dev@groovy.apache.org <dev@groovy.apache.org> >>> *Subject:* [EXT] Re: Using `var` as method return type placeholder >>> >>> *External Email:* Use caution with links and attachments. >>> Well, actually that's not true, Groovy supports creating fields and >>> properties as well with `var`, so basically everything `def` does >>> except return types. >>> >>> >>> Gianluca Sartori >>> -- >>> Cell. +39 388 1026822 >>> >>> >>> On Thu, 21 Nov 2024 at 17:41, Daniel Sun <sun...@apache.org> wrote: >>> >>> Hi Gianluca, >>> >>> `var` was introduced to Groovy just for the better compatibility of >>> Java. Java just supports declaring variables with `var`, so does Groovy. >>> >>> Cheers, >>> Daniel Sun >>> >>> On 2024/11/21 10:37:23 Gianluca Sartori wrote: >>> > Hello everybody, >>> > >>> > My name is Gianluca Sartori, from Italy, I am the author of the open >>> source >>> > project Dueuno Elements ( >>> https://github.com/dueuno-projects/dueuno-elements >>> <https://urldefense.com/v3/__https://github.com/dueuno-projects/dueuno-elements__;!!GFN0sa3rsbfR8OLyAw!dKLiRGGSN06yuMZYXThMMGLu5ES8nh1240B7mX97feXlJsWHlparG8WQWaFKj2SCDpw5PVXgiTa1KWx0GZNXc3SM$> >>> ) >>> > and I am new to this list. >>> > >>> > I would like to start using the more Java-ish `var` instead of the >>> > Python-ish `def` lexicon but I came across the fact that I cannot use >>> `var` >>> > as method return type placeholder. >>> > >>> > My understanding is that I can use `var` for both local variables and >>> class >>> > fields/properties but I cannot use it, for example, if I want to have a >>> > read only property. The code below does not compile: >>> > >>> > class C { >>> > var firstname >>> > var lastname >>> > >>> > var getFullname() { >>> > return firstname + ' ' + lastname >>> > } >>> > } >>> > >>> > var c = new C(firstname: 'Gianluca', lastname: 'Sartori') >>> > c.fullname >>> > >>> > I'd like to switch to using `var` as a type placeholder, but having to >>> use >>> > `var` for variable declaration and keep using `def` for methods >>> definition >>> > is something I don't understand. I love Groovy because it is easy. This >>> > restriction of the `var` type placeholder forces me to write code that >>> > mixes Python lexicon the new Java lexicon. >>> > >>> > My main worry is with Grails controllers where we need to define an >>> action >>> > using `def` (or `Object`) as return type and define variables in the >>> method >>> > body. At the moment we have the following options: >>> > >>> > *def* index() { >>> > *def* myVar = ... >>> > } >>> > >>> > *def* index() { >>> > *var* myVar = ... >>> > } >>> > >>> > *def* index() { >>> > *Object* myVar = ... >>> > } >>> > >>> > *Object* index() { >>> > *def* myVar = ... >>> > } >>> > >>> > *Object* index() { >>> > *var* myVar = ... >>> > } >>> > >>> > *Object* index() { >>> > *Object* myVar = ... >>> > } >>> > >>> > I would like to write controllers like this: >>> > >>> > *var* index() { >>> > *var* myVar = ... >>> > } >>> > >>> > to keep the code clean and coherent with the Groovy documentation that >>> > states clearly that *"If you think of def and var as an alias of >>> Object, >>> > you will understand in an instant."* >>> > >>> > Is this enough of an argument to ask for an implementation of `var` >>> that is >>> > fully intrechangable with `def`? >>> > >>> > Please let me know what is your opinion on that, >>> > cheers, >>> > Gianluca >>> > >>> > Gianluca Sartori >>> > -- >>> > Cell. +39 388 1026822 >>> > >>> >>>