Implicit Record Was: JEP draft: Implicit Classes and Enhanced Main Methods (Preview)

forax at univ-mlv.fr forax at univ-mlv.fr
Tue Feb 21 14:21:08 UTC 2023


> From: "Dan Heidinga" <heidinga at redhat.com>
> To: "Remi Forax" <forax at univ-mlv.fr>
> Cc: "Brian Goetz" <brian.goetz at oracle.com>, "Ron Pressler"
> <ron.pressler at oracle.com>, "amber-spec-experts"
> <amber-spec-experts at openjdk.org>
> Sent: Tuesday, February 21, 2023 2:59:59 PM
> Subject: Re: Implicit Record Was: JEP draft: Implicit Classes and Enhanced Main
> Methods (Preview)

> On Tue, Feb 21, 2023 at 2:09 AM < [ mailto:forax at univ-mlv.fr | forax at univ-mlv.fr
> ] > wrote:

>>> From: "Brian Goetz" < [ mailto:brian.goetz at oracle.com | brian.goetz at oracle.com ]
>>> >
>>> To: "Remi Forax" < [ mailto:forax at univ-mlv.fr | forax at univ-mlv.fr ] >
>>> Cc: "Ron Pressler" < [ mailto:ron.pressler at oracle.com | ron.pressler at oracle.com
>>> ] >, "Dan Heidinga" < [ mailto:heidinga at redhat.com | heidinga at redhat.com ] >,
>>> "amber-spec-experts" < [ mailto:amber-spec-experts at openjdk.org |
>>> amber-spec-experts at openjdk.org ] >
>>> Sent: Tuesday, February 21, 2023 12:33:31 AM
>>> Subject: Re: Implicit Record Was: JEP draft: Implicit Classes and Enhanced Main
>>> Methods (Preview)

>>> You seem to have a very strange notion of what "works" means. These all work
>>> just fine. No one is suggesting that local and "shared" variables are unified.
>>> If you find it confusing to teach fields early, then wait -- that's one of the
>>> choices.

>>>> Scope rules are different, being static is different, initialization rules are
>>>> different, inference rules are different, even colors in IDEs are different.

>>> Correct, and well understood. Your point?
>> Implicit class remove the "class" shell, so you now have two syntactically
>> identical things that are semantically different.
>> IMO, introducing dangling fields, a new feature in Java, does not worth the
>> confusion it creates.

> Remi, I'm slightly confused here. A local variable is declared inside a scope
> (the method) and a class variable (aka field) is declared in the implicit
> class. There's at least an obvious visible boundary around the local variable
> which provides the scoping. Students will by necessity need to understanding
> scoping fairly early when they deal with loops:

> void main() {
> for (int i = 0; i < 10; i++) {
> var double = i * 2;
> System.out.print("" + i + "..." + double);
> }
> }

> "dangling fields" is the wrong mental model for this - it's fields in an
> implicit scope. The key concept here (IMHO) is scoping which students will face
> even within a method.

Your idea of scoping fails because it's not how Java works, by example with a record, 

int value = 42; 

record Foo() { 
void bar() { 
System.out.println(value); // does not compile 
} 
} 

void main() { 
System.out.println(value); // ok 
} 

>>>> You did, by re-using the term "variables" for both local variable and fields.

>>> Sorry, no. They are both variables, but they are different sorts. Just like
>>> "instance vs static" variables, or "final vs mutable" variables. They are all
>>> variables (they have a name, and a type, and hold a value), and yet they each
>>> have different characteristics (and the characteristics can be combined; you
>>> can have shared final static variables, and local mutable variables, and....)

>>> I think you're taking a "I would prefer it work this way" and bootstrapping it
>>> into "the alternative is broken" (that's what "doesn't work" means.) You should
>>> know by now that this is the best way to not have your arguments taken
>>> seriously!
>> I think you are talking about variable in general, i'm focused on local variable
>> and fields in the context of implicit class, hence the difficulty to understand
>> each other.
>> Implicit class makes the syntax of fields identical to the syntax of local
>> variables and at the same time, the way to differentiate then is to explain
>> what an implicit class is.

> As I said above, the way to differentiate them is to talk about scoping. A local
> is scoped to the method it is declared in. A field is scoped to be shared by
> all the methods in the file (and eventually refined to be within the class).

As i said above, the scoping only works for a method or a class member, not member that are implicitly static (enum, interface or record). 

>> Again, i'm not against the notion of implicit container, i just think that
>> implicit record makes more sense than implicit class, and i would like we
>> discuss about that,
>> here is example where the container leaks,

>> void main() {
>> System.out.println(this);
>> }

>> what it should print ?

> Whatever is typically printed by Object::toString .

It can also be Enum::toString or Record::toString. 

> I don't think the goal is to **hide** the implicit class - we're not making
> this.getClass() illegal - but to take the ceremony out of the presentation so
> that students (and other users) can write simple programs before they need to
> understand class structure.

agree, 

> --Dan

Rémi 

>> regards,
>> Rémi

>>> On 2/20/2023 4:38 PM, [ mailto:forax at univ-mlv.fr | forax at univ-mlv.fr ] wrote:

>>>>> From: "Brian Goetz" [ mailto:brian.goetz at oracle.com | <brian.goetz at oracle.com> ]
>>>>> To: "Remi Forax" [ mailto:forax at univ-mlv.fr | <forax at univ-mlv.fr> ]
>>>>> Cc: "Ron Pressler" [ mailto:ron.pressler at oracle.com | <ron.pressler at oracle.com>
>>>>> ] , "Dan Heidinga" [ mailto:heidinga at redhat.com | <heidinga at redhat.com> ] ,
>>>>> "amber-spec-experts" [ mailto:amber-spec-experts at openjdk.org |
>>>>> <amber-spec-experts at openjdk.org> ]
>>>>> Sent: Monday, February 20, 2023 9:33:34 PM
>>>>> Subject: Re: Implicit Record Was: JEP draft: Implicit Classes and Enhanced Main
>>>>> Methods (Preview)

>>>>>> As i said earlier, it does not work because fields and local variables have
>>>>>> different semantics,
>>>>>> fields are initialized with a default value while local variables need to be
>>>>>> initialized before use.
>>>>>> So the curtain is just a veil that will be pierced by any students moving
>>>>>> declarations around.

>>>>> Of course it "works", it just might not work how you would prefer it to.
>>>> var greetings = 0;

>>>> does not work,

>>>> void main() {
>>>> int greetings;
>>>> System.out.println(greetings);
>>>> }

>>>> does not work,

>>>> void main() {
>>>> static int greetings;
>>>> System.out.println(greetings);
>>>> }

>>>> does not work,

>>>> void main() {
>>>> int greetings = 0;
>>>> for(;;) {
>>>> int greetings = 0;
>>>> }
>>>> }

>>>> does not work too.

>>>> Scope rules are different, being static is different, initialization rules are
>>>> different, inference rules are different, even colors in IDEs are different.

>>>>> Prior to learning about fields, the user can perceive local variables (declared
>>>>> in a method) and "shared" variables (accessible to all members of the class.)
>>>>> They can learn about their characteristics. Then, when they learn about classes
>>>>> and fields and accessibility, they can learn that the variables they were
>>>>> calling "shared" are really fields. The distinction between locals and fields
>>>>> is there from the beginning, though for most use cases, they will not notice
>>>>> the difference. When they're ready to learn the fine differences, there's not
>>>>> anything to unlearn.

>>>>>> From my personal experience, unifying local variable and field leads to more
>>>>>> pain than gain, mostly because local

>>>>> Who said anything about unification of fields and locals? Where did you get such
>>>>> an idea that this is what is being proposed?
>>>> You did, by re-using the term "variables" for both local variable and fields.

>>>>> First students will learn about statements. Then they will probably learn about
>>>>> local variables. They can be taught that they disappear when the method exits,
>>>>> and each invocation of the method gets a fresh copy. Then they can learn about
>>>>> multiple methods, and then that there are variables that can be shared across
>>>>> methods and retain their values across method invocations, and while their
>>>>> declaration syntax is the same (they're both variables, after all), the _place_
>>>>> in which they are declared is different (which is what makes them shared), and
>>>>> shared variables have slightly different characteristics (though not so
>>>>> different they have to learn this immediately). They can learn the
>>>>> characteristics of shared variables when it makes sense to teach this. And when
>>>>> the curtain is pulled back, they learn all fields have the characteristics of
>>>>> these shared variables.
>>>> Record components behave as you said, they have slightly different
>>>> characteristics than local variables and it's hard to not notice the difference
>>>> syntactically.

>>>> record Hello(String name) {
>>>> void hello() {
>>>> System.out.println("hello " + name);
>>>> }

>>>> void bonjour() {
>>>> System.out.println("bonjour " + name);
>>>> }
>>>> }

>>>> Class fields are far more different than just the lifetime but have a very
>>>> similar syntax.

>>>> Rémi
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-spec-observers/attachments/20230221/e92f4cf2/attachment-0001.htm>


More information about the amber-spec-observers mailing list