About supporting `var` of Java10+

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
33 messages Options
1234
Reply | Threaded
Open this post in threaded view
|

Re: Fwd: About supporting `var` of Java10+

Jochen Theodorou
On 11.03.2018 17:29, MG wrote:

>
>
> On 11.03.2018 14:58, Jochen Theodorou wrote:
>> On 10.03.2018 20:33, MG wrote:
>>> Hi Jochen,
>>>
>>> I was not aware that Groovy is so sophisticated in its expression
>>> analysis, that it actually uses intersection types
>>
>> you actually do not have much of a choice. It is an AST-only
>> representation only though.
>
> What I meant was: Since Groovy is for instance still using dynamic call
> site resolution in @CompileStatic mode (see: Minecraft obfuscation
> problem), it might conceivably also fall back to Object & dynamic
> resolution in such cases...

the difference is that it is not supposed to do that in static mode ;)

[...]

>> there is almost no expressions consisting of multiple expression, that
>> we can tell the type of in dynamic mode. Even something simple as 1+1
>> can in theory return a ComplexNumber suddenly.
>
> We already touched on that topic in the past: I still think that allowing
> new Foo()
> or
> Foo myFoo(...)
> to return anything that is not of type Foo is "too flexible", and
> therefore should be disallowed, or fail.
>
> Afaics Intellisense also operates on the assumption that types given are
> honored in dynamic Grooy.

Integer foo(int i) {1}
String  foo(String s) {"2"}

def bar (x) {
   return foo(x)
}

at the callsite in bar you cannot tell if foo(int) or foo(String) is
supposed to be called. Methods at runtime increase the problem, but it
is not unique to them. And it does not always have to be an override in
the classic sense either

[...]

>>>  From the view of my framework code that goes even more so for the
>>> related case of final x = RHS -> final typeof(RHS) x = RHS I
>>> therefore keep going on about - if dynamic Groovy does not pick up
>>> the RHS type for final, I need to keep my current code, or force
>>> framework users to use @CompileStatic on all Table derived classes,
>>> if they want to define table columns in the most elegant and concise
>>> way... :-)
>>
>> for "final x = ..." the exact type of x is in dynamic mode actually
>> totally not relevant. There is no reassignment, so that problem is out
>> here. But if we forget about that, then there is no difference between
>> "final x" and "def x". I know cases where it could make a difference,
>> but they do not exist in Groovy yet. so what exactly is final x
>> supposed to do different than def x besides the reassignment?
>
> class Foo {
>      final f0 = new FoorchterlichLongerNome(...) // class field c0 will
> have type Object; when analyzing the class using reflection, field
> cannot be found by looking for fields/properties of type Col
>      final FoorchterlichLongerNome f1 = new FoorchterlichLongerNome(...)
> // class field will be of type FoorchterlichLongerNome; this is the
> behavior I would wish for without explicitely being required to give
> FoorchterlichLongerNome , even in the dynamic case, for simple
> expressions (as listed above)
> }

ah, I was talking about local variables, not about fields/properties.
For me that style is more the exception. And once you move the code to
the constructor you do not get inference for the field/property anymore.
So its good only for some very specific cases. And for those to make a
difference in the dynamic mode...

bye Jochen

MG
Reply | Threaded
Open this post in threaded view
|

Re: Fwd: About supporting `var` of Java10+

MG
Hi Jochen,

there are definitely cases, which would suffice for my application and
where the return type could be deduced also in the dynamic case -
especially if you use final vars and parameters like I do ;-)
IntelliJ's Intellisense is proof of that - just press Ctrl+B at the
method call site, and it will jump to the right method definition :-)

But I am not going to argue this any further, I understand your standpoint.

Just so you understand where I am coming from: I agree that field
initialization at field declaration is unusual, but in my case it is the
only approach that makes sense:

@Table // @InheritConstructors etc
class Table PersonTable {
   final FIRST_NAME = column(...)
   final LAST_NAME = column(...)
   final DATE_OF_BIRTH = column(...)
   final SALARY = column(...)
   // ...
}

would otherwise become the unwieldy:

@Table
class Table PersonTable {
   final Column FIRST_NAME
   final Column LAST_NAME
   final Column DATE_OF_BIRTH
   final Column SALARY
   // ...

   PersonTable() {
     FIRST_NAME = column(...)
     LAST_NAME = column(...)
     DATE_OF_BIRTH = column(...)
     SALARY = column(...)
     // ...
   }
}

Any table, and view, any query result and nested query would have to be
defined taking more than double the necessary space - that would not be
Groovy, sondern Java... ;-)

lg,
mg



On 12.03.2018 07:52, Jochen Theodorou wrote:

> On 11.03.2018 17:29, MG wrote:
>>
>>
>> On 11.03.2018 14:58, Jochen Theodorou wrote:
>>> On 10.03.2018 20:33, MG wrote:
>>>> Hi Jochen,
>>>>
>>>> I was not aware that Groovy is so sophisticated in its expression
>>>> analysis, that it actually uses intersection types
>>>
>>> you actually do not have much of a choice. It is an AST-only
>>> representation only though.
>>
>> What I meant was: Since Groovy is for instance still using dynamic
>> call site resolution in @CompileStatic mode (see: Minecraft
>> obfuscation problem), it might conceivably also fall back to Object &
>> dynamic resolution in such cases...
>
> the difference is that it is not supposed to do that in static mode ;)
>
> [...]
>>> there is almost no expressions consisting of multiple expression,
>>> that we can tell the type of in dynamic mode. Even something simple
>>> as 1+1 can in theory return a ComplexNumber suddenly.
>>
>> We already touched on that topic in the past: I still think that
>> allowing
>> new Foo()
>> or
>> Foo myFoo(...)
>> to return anything that is not of type Foo is "too flexible", and
>> therefore should be disallowed, or fail.
>>
>> Afaics Intellisense also operates on the assumption that types given
>> are honored in dynamic Grooy.
>
> Integer foo(int i) {1}
> String  foo(String s) {"2"}
>
> def bar (x) {
>   return foo(x)
> }
>
> at the callsite in bar you cannot tell if foo(int) or foo(String) is
> supposed to be called. Methods at runtime increase the problem, but it
> is not unique to them. And it does not always have to be an override
> in the classic sense either
>
> [...]
>>>>  From the view of my framework code that goes even more so for the
>>>> related case of final x = RHS -> final typeof(RHS) x = RHS I
>>>> therefore keep going on about - if dynamic Groovy does not pick up
>>>> the RHS type for final, I need to keep my current code, or force
>>>> framework users to use @CompileStatic on all Table derived classes,
>>>> if they want to define table columns in the most elegant and
>>>> concise way... :-)
>>>
>>> for "final x = ..." the exact type of x is in dynamic mode actually
>>> totally not relevant. There is no reassignment, so that problem is
>>> out here. But if we forget about that, then there is no difference
>>> between "final x" and "def x". I know cases where it could make a
>>> difference, but they do not exist in Groovy yet. so what exactly is
>>> final x supposed to do different than def x besides the reassignment?
>>
>> class Foo {
>>      final f0 = new FoorchterlichLongerNome(...) // class field c0
>> will have type Object; when analyzing the class using reflection,
>> field cannot be found by looking for fields/properties of type Col
>>      final FoorchterlichLongerNome f1 = new
>> FoorchterlichLongerNome(...) // class field will be of type
>> FoorchterlichLongerNome; this is the behavior I would wish for
>> without explicitely being required to give FoorchterlichLongerNome ,
>> even in the dynamic case, for simple expressions (as listed above)
>> }
>
> ah, I was talking about local variables, not about fields/properties.
> For me that style is more the exception. And once you move the code to
> the constructor you do not get inference for the field/property
> anymore. So its good only for some very specific cases. And for those
> to make a difference in the dynamic mode...
>
> bye Jochen
>
>

MG
Reply | Threaded
Open this post in threaded view
|

Re: Fwd: About supporting `var` of Java10+

MG
In reply to this post by Jochen Theodorou
PS: Just wanted to ask what you think about the idea of making var a
compile time error in dynamic Groovy, with an error message (see
previous posting) that points the developer to @CompileStatic ?
My line of thinking is, that
# var makes no sense in dynamic Groovy in the case of var === def (in a
sense it is a ruse - like replacing every type the user gives with def)
# Someone who wants to port code from Java is actually better served by
static Groovy than by dynamic, since
## It is semantically closer to what he is used to
## Performance characteristics might also be closer to what he expects
(I know dynamic Groovy is very fast, and can be faster than static, so
emphasis is on "characteristics")
## ...and he will avoid the error of starting with dynamic Groovy
everywhere (because it looks like static Java), when in fact he would
probably be better off using dynamic code only in places where it is
actually required
*** thereby avoding surprises like e.g. null.forEach { ... } being a
valid dynamic Groovy expression and therefore not throwing, not even at
runtime ;-)
# (It would allow to introduce var in dynamic Groovy later on, with a
better semantic than var === def)

Cheers,
mg



On 12.03.2018 07:52, Jochen Theodorou wrote:

> On 11.03.2018 17:29, MG wrote:
>>
>>
>> On 11.03.2018 14:58, Jochen Theodorou wrote:
>>> On 10.03.2018 20:33, MG wrote:
>>>> Hi Jochen,
>>>>
>>>> I was not aware that Groovy is so sophisticated in its expression
>>>> analysis, that it actually uses intersection types
>>>
>>> you actually do not have much of a choice. It is an AST-only
>>> representation only though.
>>
>> What I meant was: Since Groovy is for instance still using dynamic
>> call site resolution in @CompileStatic mode (see: Minecraft
>> obfuscation problem), it might conceivably also fall back to Object &
>> dynamic resolution in such cases...
>
> the difference is that it is not supposed to do that in static mode ;)
>
> [...]
>>> there is almost no expressions consisting of multiple expression,
>>> that we can tell the type of in dynamic mode. Even something simple
>>> as 1+1 can in theory return a ComplexNumber suddenly.
>>
>> We already touched on that topic in the past: I still think that
>> allowing
>> new Foo()
>> or
>> Foo myFoo(...)
>> to return anything that is not of type Foo is "too flexible", and
>> therefore should be disallowed, or fail.
>>
>> Afaics Intellisense also operates on the assumption that types given
>> are honored in dynamic Grooy.
>
> Integer foo(int i) {1}
> String  foo(String s) {"2"}
>
> def bar (x) {
>   return foo(x)
> }
>
> at the callsite in bar you cannot tell if foo(int) or foo(String) is
> supposed to be called. Methods at runtime increase the problem, but it
> is not unique to them. And it does not always have to be an override
> in the classic sense either
>
> [...]
>>>>  From the view of my framework code that goes even more so for the
>>>> related case of final x = RHS -> final typeof(RHS) x = RHS I
>>>> therefore keep going on about - if dynamic Groovy does not pick up
>>>> the RHS type for final, I need to keep my current code, or force
>>>> framework users to use @CompileStatic on all Table derived classes,
>>>> if they want to define table columns in the most elegant and
>>>> concise way... :-)
>>>
>>> for "final x = ..." the exact type of x is in dynamic mode actually
>>> totally not relevant. There is no reassignment, so that problem is
>>> out here. But if we forget about that, then there is no difference
>>> between "final x" and "def x". I know cases where it could make a
>>> difference, but they do not exist in Groovy yet. so what exactly is
>>> final x supposed to do different than def x besides the reassignment?
>>
>> class Foo {
>>      final f0 = new FoorchterlichLongerNome(...) // class field c0
>> will have type Object; when analyzing the class using reflection,
>> field cannot be found by looking for fields/properties of type Col
>>      final FoorchterlichLongerNome f1 = new
>> FoorchterlichLongerNome(...) // class field will be of type
>> FoorchterlichLongerNome; this is the behavior I would wish for
>> without explicitely being required to give FoorchterlichLongerNome ,
>> even in the dynamic case, for simple expressions (as listed above)
>> }
>
> ah, I was talking about local variables, not about fields/properties.
> For me that style is more the exception. And once you move the code to
> the constructor you do not get inference for the field/property
> anymore. So its good only for some very specific cases. And for those
> to make a difference in the dynamic mode...
>
> bye Jochen
>
>

1234