Discussion on boilerplate for code tightly bound to OOP
John Hendrikx
hjohn at xs4all.nl
Thu May 19 07:00:32 UTC 2022
>The problem is something that Java's had for quite some time, and is one of
>the main issues that earns it quite a bad reputation[1] amongst developers
>(Even if some of that disdain is outdated and has already been rectified in
>newer Java releases)- The language is simply too verbose/has too much
>boilerplate, and Java code itself is too tightly linked to classes[1] (at
>least on the semantic level; Languages like Kotlin support other paradigms
>like functional code even though they ultimately compile down to Java
>classfiles).
Isn't the link mentioned in [1] a parody? "Java for the Haters in 100
Seconds" seems click bait to me. The entire channel seems full of this
click bait, for many languages and anything else they can get clicks
for. The author even links to another video saying "just kidding". Not a
very credible source for anything IMHO as the need to commercialize the
content is probably more important than providing impartial and accurate
information.
>Of course, like I did mention above, quite a number of these issues are
>already being tackled (records, accessors for arbitrary classes, talks
>about deconstructors, with expressions, future reified generics, potential
>operator overloading in Valhalla with values and primitives), which is a
>great thing, but Java is still having trouble catching up with modern
>developer expectations and other languages as a whole.
According to who is it having trouble catching up? My expectations of a
modern language are that it is backwards and forwards compatible, that
it is predictable, stable and highly readable.
Readability is something that very few languages get right. It for
example means that there aren't too many different ways of accomplishing
the same thing, and what ways are available should be useful to all
developers in common situations in order to be recognizable. It also
implies that things are not hidden from the developer. A snippet of Java
code taken out of context can usually be interpreted relatively
unambiguously, because the context is limited in how it can affect that
snippet. A feature like a preprocessor (#define from C) would ruin this.
As would import aliases as convenient as they may seem. Already static
imports diminish readability somewhat which is why they're often
restricted for specific uses only (like test code). There is a
precarious balance between readability and conciseness; more concise
code often needs more context and thus more effort from the reader to
interpret.
>While many of these
>complaints are often fueled by hype and personal opinion and provide no
>constructive value as feedback whatsoever, there are still many salient
>points to address, in this case it's how the language is too forceful with
>OOP.
I never felt the need to write functions without a class, in fact, the
class helps to add good name space for groups of related functions,
avoiding repetition in the function names themselves. Java enforcing
structure on your code, its novel take on one class = one file and how
they're organized in packages is a large part of why it is (I refuse to
say "was") so successful. In other languages, all these things we take
for granted in Java are not standardized, may differ per project or even
per file. Newcomers to Java may be bewildered a bit about this way of
working (if they had prior programming experience), but that pays
dividends when switching from code base to code base and not having to
learn a new way of how things are organized every time.
>It's not much of a secret that if one wants to write simple, procedural
>Java, they have to fight the language substantially to do so. Classes have
>to be marked as final, their constructors privated and made to throw an
>exception if reflection is used on them anyway, and every method has to be
>marked as static.
These are self imposed restrictions, popularized by tools that will flag
these as "problems". I don't see these as problems, and so these
warnings get disabled. There is no need to write such a private
constructor, nor is it a requirement to mark such a class as final,
apart from satisfying an IMHO dubious warning that is much better
addressed with the warning at the call site (calling a static method in
a non-static way).
Something similar happens with serialVersionUID. People satisfy this
warning by adding a generated id (based on the current class structure)
but have no intention of ever using the mechanism. The field is just
some very ugly random noise in this case. A much more sane approach is
to turn the warning off, or if you are specifically writing with
serialization in mind, it is probably better to start from version 1L.
The only reason to use the generated ID is if you already serialized
these classes before ever giving serialization some thought and need to
remain backwards compatible with serialized data from previous versions
of your code.
>At first glance, this might just seem like a mild
>inconvenience and one would wonder why this is an issue, but this becomes
>incredibly repetitive and frustrating when made to scale, which will
>undoubtedly drive developers off when considering it as a language of
>choice (Even with a simple "Hello World" jar, many newcomers are often put
>off with how much code is required, which is the last thing we'd want to
>happen). Much of this extra verbosity from having procedural code (unlike
>with statically typing a variable or a method's return type for instance)
>is also a tradeoff without any benefit as well, and there doesn't seem to
>be much of a reason to make developers pay such heavy penalties if we can
>help them out with new language features, even more so since "mutating"
>value classes was already considered too painful in the amber drafts (Also
>from[2] "You get more typing practice?" "The shares for keyboard
>manufacturers go up?" "You can sell software to generate this <Expletive
>omitted> automatically?").
I think not too much weight should be attached to these kinds of snark
comments.
>It could be argued that this could all be avoided by embracing OOP
>entirely, which is certainly one of Java's biggest strengths, but there are
>many instances where the procedural approach would be significantly easier
>to implement the program's logic in (think the number of Java codebases
>that have static only utility classes), or where forcing OOP would actually
>degrade both code quality and performance (deeply nested chains of object
>pointers or pointless object allocations for instance).
In what way will not having to type a class wrapper around a set of
(hopefully) related functions make things **significantly** easier? How
will these functions be imported in another class, or are you suggesting
code bases with just a single source file, inevitably leading to a huge
unreadable jumble of functions? A class acts as a convenient name space
to keep things organized. It is a requirement as the alternative seems
to be leading to global functions.
Also, what deeply nested chains of object pointers or pointless object
allocations are you referring to? It seems to refer to what people new
to the language might be doing, which although regrettable, is I think
not so much a Java language problem but more a general lack of
familiarity with OOP. IMHO it is best to stamp this out as early as
possible instead of encouraging further by providing more lenient
syntax.
> There's also
>another problem in that this forceful approach also causes newer developers
>to learn rather harmful and over-the-top notions of OOP and how everything
>must be a class and object- To the point that there is even an entire talk
>for how to unlearn the rigid and incorrect concepts of OOP for people
>coming to other languages from Java[3]. Given how popular of a language
>Java already is despite the number of complaints against it, we should be
>careful to not be the ones responsible for "poisoning" individuals new to
>programming with the idea that everything has to be in a class- This does
>no one any favours, not us, nor the learning programmers who may end up
>harming the ecosystem at large once their assumptions are deeply rooted.
So you are saying that other languages that use different paradigms are
hurt by the paradigms in use in Java and that Java therefore should
conform more to these other languages? I think Java is actually better
for exactly the reason that it doesn't try to be two things, by catering
both to professional and casual Java developers.
Casual Java developers (by which I mean developers that are well versed
in other languages, but sometimes do some Java side work) will have
totally different views on what is essential to a language, heavily
inspired by their language of choice. They will be writing in their
primary language (C code for example), and then make minor changes to
make it compile in Java. They'll be unaware of Java's paradigms, its
standard library, its conventions, its ecosystem, and will be frustrated
that Java is so much harder to use than their primary language. I've
seen code written like this and it should not be encouraged, just like
how the video mentioned in link [3] is discouraging how things are done
in Java in their language of choice. Given Java's success and market
share, I think those languages would benefit from being more Java like
instead.
>Maybe Java's current verbosity when it comes to procedural code could still
>be an advantage for enterprise applications, where being as explicit as
>possible with boilerplate can be helpful when reading a codebase, but that
>would be a rather shortsighted view. It would be favourable for Java to
>become a well liked choice for general purpose utilities such as regular
>desktop applications or quick and small ones written out of convenience for
>instance, and limiting it to enterprise-only would make its ideal users
>only a very specific group- Not good if we want it to stay competitive. Not
>to mention that a new language feature for facilitating procedural code can
>indeed be explicit without much of the boilerplate of static only
>classes, if designed properly. This would also help in hiding the
>implementation detail of ultimately compiling down to classfiles, bypassing
>the issue mentioned above entirely, since to the developer there is
>technically no class involved whatsoever- Just methods. You could even get
>IDE support for checking whether reflection attempted to call a constructor
>at compile time too!
>
>In the end, it certainly doesn't help with Java's image (and potential
>newcomers to the language) that a common view of it by many developers out
>there is that it's reluctant to include newer language features
>because "<Expletive
>omitted> you, I'm Java"[2], which is a reputation we can do without, and I
>feel that this discussion would be a good place to start in dispelling that
>view of Java that many developers have today.
You linked to a 9 year old Reddit post on /r/Java -- these posts are on
Reddit all the time, and commonly trolled by the same group of people to
express their dislike for anything Java. I'm not sure we need to cater
to this group of people, as nothing will ever satisfy them. Even when
their points are outdated and addressed in current versions of Java,
they'll just back peddle and switch their argument to how everyone is
using Java 8 still.
Best regards,
John Hendrikx
>
>Links:
>[1] https://www.youtube.com/watch?v=m4-HM_sCvtQ&ab_channel=Fireship
>[2]
>https://www.reddit.com/r/learnprogramming/comments/1cv8rb/why_does_java_get_such_a_bad_rep/
>[3] https://www.youtube.com/watch?v=o9pEzgHorH0
>
More information about the amber-dev
mailing list