Yeah, I liked the idea of restricting static members for about thirty seconds, and then came around to the same place Dan is.  It seems superficially attractive to say "if you need statics, you should be aware of classes", but I don't see how it really helps students, and the error messages that the user would get in this case ("it's time for you to grow up and declare a class!") are not likely to be all that educational.  Users may, for example, want to cut and paste snippets of Java code from blogs to try them out, that might have static in it, and there's no reason this shouldn't work.

So after wrestling with Ron's question briefly, and being briefly tempted, I think the temptation is best resisted.

I like Dan's rubric about "need to use the name", with the understanding that in order to create more than one instance, you need to use the name.  Having more than one instance of a class is a good time to understand that you are defining an abstraction, not just a simple program.  In the world where you get one implicit instance, it is still ambiguous whether this is a program or a class (which is good if you don't know what a class is.)  The need to understand classes will likely come through "I want more than one instance."

(BTW I can imagine a world where records are taught before classes; a simplified class could need to describe "pair of name and grade", and they could use a "nested" record for that, and still not have to learn yet what a class really is.)

On 2/17/2023 11:56 AM, Dan Heidinga wrote:


On Fri, Feb 17, 2023 at 11:05 AM Ron Pressler <[email protected]> wrote:

    I’d like to make another point about the general approach of this
    JEP.

    We try to avoid a beginners’ dialect, but a beginners’ *subset* is
    also not what we’re proposing. While the feature is primarily
    motivated by education, it is also a natural, perhaps even
    obvious, feature for Java that’s perfectly in tune with the
    existing features of the language.

    Classes, packages, and modules are all programming-in-the-large
    constructs, and every Java method resides in a class that resides
    in a package that resides in a module. Yet, when you don’t need
    encapsulation, an unnamed module is implicitly provided; when you
    don’t need package namespacing, an unnamed package is implicitly
    provided. It makes sense to do the same for classes even to reduce
    the need for programming-in-the-large declarations in small
    programs. Of course, helping students is a bigger motivation that
    makes significantly raises this feature’s priority.

    The important question as is whether or not this feature fulfils
    the motivation of helping beginners (of course, it’s not the only
    feature we can or will do to that end). I think the answer is yes.
    So then the remaining question is, would subsetting the language
    to forbid static members significantly help students? I’m not sure.


Wouldn't forbidding static members impose a cliff on beginners?  As they learn about static methods and fields and introduce the first static member to their implicit class, they'd be forced to grow a class structure around their program. Maybe that's a natural time to have to talk about defining a class?

I think there's a benefit in letting students (and advanced users) use as much of the language as possible in implicit classes.  Don't force them to define the class until they do something that requires the class to have a proper name.

--Dan


    — Ron

    On 17 Feb 2023, at 10:11, Ron Pressler <[email protected]>
    wrote:



    On 16 Feb 2023, at 21:41, [email protected] wrote:


    I still think that fields should not be allowed inside an
    implicit class, because when you remove the class declaration a
    field and a local variable are too similar and because an
    implicit class has no user defined constructor.

    I think your general point has some merit — I’ll get to that
    later — but first let me address the concrete points you raise.


    Here is a series of examples showing how confusing it can be.


    How would any of those be made easier to understand by the
    presence of a class declaration when you don’t know what a class is?

    By the way, we should certainly look into making some error
    messages — especially those encountered by beginners — easier to
    understand.

    Also conceptually, being able to define fields without
    constructors is problematic, because you are bypassing the the
    notion of encapsulation.


    Encapsulation from what? Encapsulation is a
    programming-in-the-large notion, but even at the technical level,
    an implicit class is well encapsulated by virtue of it being
    unnamed (and the default access remains package).

    Implicit class instance fields are more complex that usual class
    fields because of the lack of constructors.

    I’m not sure I understand the relationship you make to
    constructors (BTW, you can define initializers).

    Python and JS, both also first language have a notion of shared
    variables that can be introduced before object fields. Clojure
    and ML, both functional languages, also have a similar notion of
    shared variables. Even Haskell has constants. Surely you’d agree
    that at least final fields — constants — are necessary to do any
    kind of nice programming?


    Teaching using a simpler model is great but not if as a student
    you have to unlearn something previously introduced.

    I wholeheartedly agree, but what is the thing that needs to be
    unlearned?

    But now back to where I think your general point has merit. I
    think final fields are a must, but one could certainly argue that
    non-final fields are not. You can certainly do a lot of
    programming without them. But I think that allowing final fields
    and disallowing non-final fields *in Java* would be weird,
    because to designate something as final you need extra syntax, so
    we’d reject syntactically simpler, valid, code and accept more
    complex one. Moreover, there are things that are easier to do and
    tech with mutable fields.

    However, there’s the matter of static, which you used in your
    examples but didn’t explicitly discuss. Because a an implicit
    class is effectively a singleton (plus, the class cannot be
    referenced by other classes), there is no useful difference
    between an instance field and a static field, so I think we
    should entertain the notion of disallowing static members —
    fields, methods, or even member classes (although things that are
    implicitly static, such as records would obviously be allowed).

    One argument against that may be is that if an experienced Java
    programmer has an existing small program that they want to make
    prettier by turning into an implicit class — implicit classes are
    mainly motivated by learners, but they’re not *just* for them —
    then the process would be made harder by disallowing static members.

    In short, I think we must allow fields, but we can think about
    disallowing (explicitly) static members altogether.

    — Ron


Reply via email to