JEP-476 module import considered harmful
Cristian Mocanu
cvmocanu at gmail.com
Tue Nov 19 15:17:51 UTC 2024
Hi Brian,
I apologize for appearing to be attacking the persons behind the proposal.
That was not my intention. I intended simply to give my reasons why I think
import modules are a bad idea.
To engage with the idea - not with the people :)
> code that has reached the mature phase of its lifecycle, and for which
stability has become the most important consideration
I can see how sometimes proof of concepts are being abandoned - and maybe
this happens more when developing Java itself or a library. But in most
projects, proof of concepts become the main product, which makes it
necessary to write quality code even for a proof of concept.
> - Single-class imports have tradeoffs that go beyond the mere “typing
less”. It also means _reading less_; not having to grovel through hundreds
of import lines to get a sense of the dependencies. Java developers
complain about this as an aspect of Java’s “boilerplate”.
You can always read less - just skip reading the dependencies. Moreover, to
avoid SCM conflicts, you should force a build failure if the imports are
not sorted. And if the dependencies are sorted, it's easy to see the common
prefix. Having (sorted) individual classes in the imports is even better to
give you a sense of the dependencies - you get a sense of how much a
particular module is used.
Regarding boilerplate: junior developer don't understand that there are 2
types of boilerplate:
* boilerplate that doesn't add to the readability of the code
* boilerplate that makes the code clearer (like extracting local variables,
just to have an explanatory name for a part of an expression)
The first type should be avoided, the second type is desirable.
> - For new code (or new developers), the fussiness of imports is an
impediment to getting things done.
I fail to understand the difference between (1) letting the IDE write the
import for me for new code, vs (2) letting the IDE write the import for me
for code that needs to be kept stable.
> - Expressing a dependency on a package or module is a more abstract
statement than a single class.
> - Expressing a dependency on a module is _intrinsically more sensible_
than expressing it on all (or most) of the packages in a module.
We already have a place for that: Gradle or Maven (or the
`module-info.java` for people using modules)
> Users who want to “use Jackson” have to grovel through tutorials to
figure out which packages to import.
In 20 years of programming, I **never** had to look up what package to
import. Again - developers don't write import statements by hand - the IDE
does it for us. I just type `ObjectMapper` and the IDE will write the
correct import (or let me choose, if multiple classes with that name are
available in the classpath).
> - Having modules be the unit of dependency, but packages be the unit of
import, is an accidental asymmetry that should be corrected.
I, and many of the devs I worked with, use packages as a replacement for
namespaces from C# - it's a total mess to have a lot of classes inside a
single package.
> Most modules (java.base notwithstanding) have a single purpose an a
single “import module com.foo.WhizzyJsonParser” is a clear statement of
semantic intent. In fact, this is sometimes a _clearer_ statement of
intent than importing all the individual classes.
I agree - but we already have `module-info.java` for this.
> - The preference of some for star imports is a preference; this isn’t
really a good argument for “so no one should be allowed to code like this"
I didn't merely state that star imports are bad (which would be a mere
opinion) - I gave arguments to back my assertion: they introduce confusion.
Maybe you think there's no confusion being introduced, or that the
confusion is justifiable. I guess sometimes we have to agree to disagree.
> Which is to say, _sometimes_ the benefits of star imports do not exceed
their costs. And in those cases, you are correct, you should not use
them! But that doesn’t make them intrinsically bad, or mean that we should
force single-import on all users because they are not ideal in all
contexts.
Do you have **any** case in particular where the benefits exceed the added
confusion ?
> Finally, one more point on the sky-is-falling rhetoric: it’s not
helpful. We saw this with local variable type inference (var); many
developers catastrophized loudly that this would destroy the readability of
Java code, but that didn’t happen.
I'm sorry for coming up this strong. I should have just stated the
arguments against it, and leave it at that.
I'm glad you brought up `var`, though. In my experience, `var` makes the
code more difficult to understand much more often than the cases where it
clears up things. In other words, we have a feature that makes the code
more complicated (harder to understand) more often than not. I wouldn't
have added such a feature to the language, just to satisfy people used to
non-statically-typed languages.
Kind regards,
Cristian
On Tue, 19 Nov 2024 at 15:07, Brian Goetz <brian.goetz at oracle.com> wrote:
> This mail would have benefited from some additional thought before writing
> (and especially before turning the “this is a disaster” knob to 11 or
> trotting out the overused trope of “considered harmful”.)
>
> Yes, OF COURSE some people dislike star imports, and with some vaiid
> reasons, including the ones you raise. Did you think that there was even a
> tiny chance that we were not aware of this? Someone of your extensive
> experience should be able to go through the thought process of:
>
> - I think this is a bad idea
> - But, smart people who think deeply about language evolution and its
> impact on the world of code through about it for a long time and came to a
> different conclusion
> - Perhaps there is more to it than I think, I should inquire
>
> before writing such a jumping-to-disaster mail. (I think also you
> misunderstand the motivation for why most style guides disrecommend star
> imports; it is not primarily readability, as no one in the real world
> actually reads imports, and questions of “where is this class” are well
> handled by IDEs; the primary motivation is usually stability, which comes
> from its explicitness.)
>
>
> So yes, all of these arguments were well understood from the outset, and
> were discussed during the design process. What is missing from the “but of
> course everyone knows this” analysis is that the concerns over star imports
> have a context: code that has reached the mature phase of its lifecycle,
> and for which stability has become the most important consideration.
> Within that context, these concerns are valid, but this context does not
> remotely cover the whole experience of writing Java code.
>
> Some of the countervailing considerations included:
>
> - Single-class imports have tradeoffs that go beyond the mere “typing
> less”. It also means _reading less_; not having to grovel through hundreds
> of import lines to get a sense of the dependencies. Java developers
> complain about this as an aspect of Java’s “boilerplate”.
> - For new code (or new developers), the fussiness of imports is an
> impediment to getting things done. The arguments about stability do not
> apply here, and enforcing them “for your own good” seems almost kind of
> mean.
> - For codebases that prefer single imports, automated refactoring is
> widely available, so starting out with module or package imports is not
> creating a long-term problem.
> - Expressing a dependency on a package or module is a more abstract
> statement than a single class.
> - Expressing a dependency on a module is _intrinsically more sensible_
> than expressing it on all (or most) of the packages in a module. Users who
> want to “use Jackson” have to grovel through tutorials to figure out which
> packages to import.
> - Having modules be the unit of dependency, but packages be the unit of
> import, is an accidental asymmetry that should be corrected. Most modules
> (java.base notwithstanding) have a single purpose an a single “import
> module com.foo.WhizzyJsonParser” is a clear statement of semantic intent.
> In fact, this is sometimes a _clearer_ statement of intent than importing
> all the individual classes.
> - Even within the context of stable, mature code, dealing with emergent
> name clashes requires only trivial remediation. So even such codebases may
> prefer the more abstract expression of module dependency because the costs
> of mitigating the resulting instability is low.
> - The preference of some for star imports is a preference; this isn’t
> really a good argument for “so no one should be allowed to code like this"
>
> Which is to say, _sometimes_ the benefits of star imports do not exceed
> their costs. And in those cases, you are correct, you should not use
> them! But that doesn’t make them intrinsically bad, or mean that we should
> force single-import on all users because they are not ideal in all
> contexts.
>
> Finally, one more point on the sky-is-falling rhetoric: it’s not helpful.
> We saw this with local variable type inference (var); many developers
> catastrophized loudly that this would destroy the readability of Java code,
> but that didn’t happen.
>
>
>
>
>
> On Nov 19, 2024, at 4:49 AM, Cristian Mocanu <cvmocanu at gmail.com> wrote:
>
> Hello,
>
> My name is Cristia Mocanu, and I am a Java developer with almost 20 years
> of experience.
>
> I was made aware of "JEP-476 module import" recently.
>
> I strongly recommend making sure this JEP is abandoned and never gets
> merged into Java.
> The reason is that a module import shares the same problem with the star
> import: it makes the code much more difficult to understand without an IDE
> (e.g. when reviewing a PR on GitHub).
> The problem with the star import is so bad, that many official code
> styles, and many teams I worked in, explicitly forbid star imports, making
> the build fail if one is found (i.e. by using Checkstyle's AvoidStarImport
> rule).
>
> The module import, just like the star import, will have the very bad
> effect of encouraging people to write code that is difficult to understand.
> The advantage would be that the VIM guy can type less when writing a Java
> file. Don't get me wrong, I use VIM myself (even the IdeaVim plugin), but
> the last time I wrote an import manually was probably 15 years ago - in the
> real world, we type the class name, and IntelliJ or some other IDE writes
> the import for us.
>
> With fewer words: this JEP has nasty disadvantages, without providing any
> real world benefit.
>
> Kind regards,
> Cristian
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-dev/attachments/20241119/ba9b7a53/attachment-0001.htm>
More information about the amber-dev
mailing list