> > var was always intended for the case of "type inference from an > assignment", the way it is used in Java, and imho that is also what people > coming fom other languages would expect. >
My perception is that a feature like `var` is useful only when you cut-and-paste a Java code in a Groovy file, what is the use case that needs type inference in a dynamic language? People coming from what languages? Let's give a look at the top 3 languages: - TIOBE (https://www.tiobe.com/tiobe-index/) says: Python, C++, Java - PYPL (https://pypl.github.io/PYPL.html) says: Python, Java, JavaScript Python -> Uses `def` and is a dynamic language Java -> Introduced `var` in Java 10+ only for local variables to avoid writing the Type twice in most variable assignments and in loops mainly C++ -> Introduced `auto` in C++ 11+ to assign variables providing type inference and as a return type in methods providing runtime evaluation of the return type Javascript -> Used `var` to declare variables Then we have Groovy -> Uses `def` as a Type Placeholder for Object in variables/fields/property definition and methods return type. Groovy introduced `var` in Groovy 3+ to support cut-and-paste of Java code in a Groovy file, `var` is an alias for `def` but it cannot be used as a method return type. > var is the same as def, i.e. the Object type, just with less applicability > than def, since, afair, we wanted to at least keep the door open for > supporting type inference through var in the future. To now make it a > full-on alias for def would more or less prohibit that. > What is the use case where a Groovy developer needs a specific new keyword for type inference? This is something I don't understand, sorry for being stupid but that's just me. Java developers have mixed feelings and opinions about `var`, it was not embraced as a miraculous feature added to the language. I mean if it wasn't for Java introducing `var` Groovy would have never felt the need for it by itself. Apart from that, I agree with Eric that var goo() also looks semantically > wrong. > Give it a try thinking "This method returns a variable" because that is what I think every time I see `def` as return type, because that's the way it has been documented for 20+ years. For sure I don't think the same when I see `def` in Python because it was never documented that way in the last 30+ years. > I also think the "Python vs Java lexicon" argument is quite weak, since > def is not Python specific, and has been in Groovy since the beginning... > I give you this, I am just trying to make a sense out of it. If you don't like the "Python vs Java lexicon" you can think of it as "Groovy vs JavaScript lexicon" or "Groovy vs Go lexicon" or whatever languages you like more. We are dealing with the Java 'var' here. *TLDR:* > If you want the semantics of def in Groovy, you should use def everywhere > (as Groovy developers have done for decades), and not use var, which at > this point only exists to satsify Groovy's goal of maximum Java syntax > compatibility where possible, and in a possible future extension could > support type inference, which is probably not what you want/expect when > using var as a synonym for def :-) > I would keep using `def` but there was a discussion in another group to use `var` in a Groovy project the way Java uses it, to attract Java developers. That triggered me to open this discussion. If we want Groovy to be more attractive to Java developers we should give them the "Groovy var" which is compatible with Java without giving Groovy something it would have never needed by itself. I don't really see any reasons to add a new feature in Groovy that acts like it acts in Java to cover the only use case of cut-and-paste Java code in a Groovy file. I mean, are we really covering just the "cut-and-paste" use case? Because that is not even a real use case to my mind, when you copy code from one language to another you do reformat it or rewrite it. And how many times would you copy a Java code in a Groovy app? Even if it was 50 times in a year for each Groovy developer that exists in the world I would not have chosen to implement `var` to mimic what the Java 'var' does. But I am ignorant, so I can say stupid things, please don't get triggered too much by that. That is just my subjective, personal and stupid opinion. Because what happens is that people start thinking it is a new Groovy feature they should start using. And that feature is against the nature of Groovy (var v1; var v2 = null would not be valid anymore) > > Cheers, > mg > > > On 21/11/2024 22:04, Milles, Eric (TR Technology) via dev wrote: > > When support for var was installed, the path taken was to make it work > more or less like def. That is not to say it is identical to def, since we > did make sure to support the name "var" — reserved type name and not > keyword. This was a fitting choice given our close-to-Java semantics. We > don't want compatibility issues, but some do exist. > > The way def works is to indicate a "dynamic type" in most cases. This is > equivalent to java.lang.Object in many circumstances. > > I understand your request to have var work everywhere that def does so you > can stop using def altogether. > > My preference would be for var to be used for the same local variable > circumstances that Java defines. But we have not implemented the type > inference that Java provides; STC gives a close approximation. > > So if you can use var for field/property, I would consider deprecating and > later removing that. It may not have been intentional since the grammar > shares rules for fields and variables. > > ------------------------------ > *From:* Gianluca Sartori <g.sart...@gmail.com> <g.sart...@gmail.com> > *Sent:* Thursday, November 21, 2024 2:39 PM > *To:* dev@groovy.apache.org <dev@groovy.apache.org> > <dev@groovy.apache.org> > *Subject:* Re: [EXT] Re: Using `var` as method return type placeholder > > If we want Groovy to just accept `var` as it is used in Java we should > also reject an un-initialized variable definition or a "var v = null' since > the type cannot be inferred and it would not be accepted by Java. > > My take on this argument is that "Groovy digests Java but Groovy is not > Java" and instead of talking about "semantics" we may talk about "lexicon' > when discussing about `def` (Python lexicon) and `var` (Java lexicon) but > the semantics remains the same: they are both "type placeholders" in Groovy. > > > > Gianluca Sartori > -- > Cell. +39 388 1026822 > > > On Thu, 21 Nov 2024 at 21:25, Gianluca Sartori <g.sart...@gmail.com> > wrote: > > 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://urldefense.com/v3/__https://docs.oracle.com/en/java/javase/17/language/local-variable-type-inference.html__;!!GFN0sa3rsbfR8OLyAw!fVG_R8uSV1w8CBE28pxva8IPqDXIa3kKPXm4EjFrGpedbb-Pa2pkpPYmYnvElEsS1Xl1-4ATLOWNvnFzCl3pidAa$> > 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://urldefense.com/v3/__https://groovy-lang.org/semantics.html__;!!GFN0sa3rsbfR8OLyAw!fVG_R8uSV1w8CBE28pxva8IPqDXIa3kKPXm4EjFrGpedbb-Pa2pkpPYmYnvElEsS1Xl1-4ATLOWNvnFzCgg5WHYn$> > 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://urldefense.com/v3/__https://groovy-lang.org/semantics.html*_variables_vs_fields_in_type_inference__;Iw!!GFN0sa3rsbfR8OLyAw!fVG_R8uSV1w8CBE28pxva8IPqDXIa3kKPXm4EjFrGpedbb-Pa2pkpPYmYnvElEsS1Xl1-4ATLOWNvnFzCmjwZaoW$> > 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 > > > > >