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