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
>>> >
>>>
>>>

Reply via email to