

Next-gen Java Programming Style - fogus
http://codemonkeyism.com/generation-java-programming-style/

======
WilliamLP
> Do not use loops for list operations.

I can not get behind this in Java if the filter, fold, or map operation is
simply a one-off. (It's another matter entirely though if the power of the
functional approach is useful in the situation, say if a filter should be
switched dynamically.) To do this for something static though, such as
eliminating empty strings or adding an array, is just worse than useless.

This is as clear an example as any of programming against the language, not
into it. The code is longer, it is slower, and _for a Java programmer_ it is
much less clear. Java was explicitly designed not to be a language for showing
off cute constructs for their own sake.

~~~
darkxanthos
The code is longer: Without having something like extension methods this might
be the case. I'm a C# dev so I'll partially concede here due to ignorance.
That predicate syntax really does suck... it'd be nice if you had lambdas but
[shrugs]

The code is slower: It is slower but in my experience it is very rare that our
performance bottle necks occur in these sections of code. We have actually
profiled our code and changed from for loops in the legacy version to a
redesigned version of the class using this more functional approach during
refactoring and we can meet our performance needs just fine. More often than
not the big performance improvements lie in disk i/o or more intelligent
algorithms rather than just a general use of more functional idioms.

Much less clear _for a Java programmer_: Isn't that always the case until
programmers start to learn other ways of doing things? If this was just one
guy and not what appears to be a industry wide sea-change maybe I wouldn't
argue. The functional paradigm however is being given a fair amount of
attention and I don't think it's something you can classify as a niche
concern.

"cute constructs for their own sake"- I believe the point of developers moving
away from loops is that we are starting to realize that explicitly asking the
compiler to loop through these items in this particular order is over-
specification 99% of the time. Really we are just saying do this to each one
of these. By shifting to a functional paradigm these types of tasks can be
easily parallelized and abstracted to the point that you really care about.

~~~
swolchok
How much power is wasted worldwide by slow code that isn't the bottleneck?
Surely, fast habits are better than slow habits, all else being equal.

~~~
davidmfoley
How much power is wasted worldwide by misguided programmers doing premature
optimization? All else is never equal.

------
KirinDave
Bizarre advice. Throw away the mutable aspects of Java to try and code in this
"new hotness", a pale echo of an OCaml-esque style of programming. In the
process you make code that is neither as declarative as functional code, nor
elegant as Java code. Stop trying to code like another language and _use
another language_.

That's enough for me to discard this article as chaff, but considering it even
further, has anyone stopped to ask how the Java runtime and compiler handles
these changes? Making new classes instead of mutating existing ones doesn't
strike me as an efficient use of the system.

Finally, I am so sick of people lamenting being "trapped" in Java. This
nonsense of being "trapped" is just a shield for people who don't want to go
through the hassle of really using a different language. If I can squeak new
languages in at Lockheed Martin on a huge spacerange project who's spec was
literally conceived when I was still in diapers, then anyone can do it
anywhere if they have the will.

~~~
cturner
In some spaces (financial, perhaps military) running the JVM is the only
sensible thing to do. It has special status that allows you to skip steps at
audit, which allows your customers to install it, it allows you to use
libraries and it's really good for cross-platform so long as you don't care
about GUIs (and with everyone using web these days, there's no reason to care
about GUI).

~~~
tjmc
True, but who's to say you can't use another language _in_ the JVM - eg.
JRuby, Jython or Clojure

------
jimbokun
"Refactoring is easy, should you need it. If you do not control all the code
and it’s usage, you might need to be more careful though."

Bloch's Effective Java is wonderful, but if it has a weakness, it might be
that it assumes everyone is writing a library to be used by a lot of
developers, many of who are outside your organization.

The example of public fields in data transfer objects is an example of this.
Making the fields public is fine if this code is just for you and your team,
because you can always refactor it to use accessors later if you need to. But
if this code is in a library used by people outside your organization,
introducing accessors later without breaking code will be almost impossible.

~~~
JulianMorrison
Public fields like that announce that the object is actually an immutable
struct with _no_ internal workings. A need to change it to add computed (or
worse, mutable) fields is probably a code smell.

------
dcminter
This is one programmer's opinions dressed up as a definitive list. We might as
well be discussing bracing preferences - always futile without _evidence_.

For what little it's worth:

1\. Minor benefit as noted. Most devs don't do this. Note that in point 3 his
sample loop doesn't declare the loop item final so I doubt he does it all that
often either.

2\. Ok so far as it goes.

3\. What objective benefit am I supposed to get here? If we're pulling
preferences out of our bums, I'll go for meaningful names in loop variables
thanks.

4\. Says who? AT&T braces for the win!

5\. Not my preference. Fails the YAGNI principle certainly (which he's
apparently in favour of in point 2).

6\. Who says it's too hard to use? For simple threading problems the existing
tools are more than adequate.

7\. Again, what benefit does this convey? It's used in a few places in Java
(StringBuffer/Builder) but hasn't proven popular more generally. I suspect
there are good reasons for that.

8\. Not wildly unreasonable, but Getter/Setter pairs often turn out to be
necessary in fairly short order.

------
JulianMorrison
What makes me laugh is the commenter defending getters and setters as
encapsulation.

No, what getters and setters are is a huge verbose door cut _through_ your
encapsulation, turning a class into a mere vending machine.

~~~
bkudria
Agreed. Probably his confusion stems from the fact that Java can expose
properties directly. Eww.

------
Xixi
I have to admit that the 5th point (Use many, many objects with many
interfaces) leaves me thinking...

On the one hand I understand where the author wants to go : by implementing
many many interfaces you eventually sort of "emulate" duck-typing, while at
the same time reinforcing type safety (specially when it comes to String).

On the other hand, it sounds like a good way to make something that was
verbose to begin with even more verbose... but maybe I'm mistaking. I don't do
much Java recently (some GWT/GXT sometimes), but I will probably give it a
practical try...

~~~
jrockway
The problem I see is the amount of code that has to be copy-pasted, due to
Java's lack of traits. If you want to write code like this, do yourself a
favor and write it in Scala instead.

~~~
sciolizer
Java's lack of traits does indeed suck, and I would definitely prefer Scala
over Java, but the only copy-pasting you need to do is of delegation methods.
It's duplicate boilerplate, but it's not duplication of logic.

------
mcormier
Although I do agree that you shouldn't reassign a parameter I don't agree with
using the final keyword everywhere. Any decent koder knows not to modify a
parameter. If you want to enforce something like this then parse the code on
check in and refuse the check in if a parameter is modified. Don't bloat the
kode with a reactionary workaround.

~~~
profquail
So having to write extra code to extend your versioning system to parse
whatever language your code is in and then check it to see if you've altered a
variable value doesn't increase bloat, but adding the 'final' keyword does?

There are other problems with that idea, the first of which is that if someone
else takes your code and extends it (say, for an open source project) they
won't have the same "checking system" that you have, and so it won't catch
their mistakes (while using "final" would). Also, I'm not a Java programmer (I
mostly use C# or C), but marking classes/methods/variables in C# as 'sealed',
'final', 'static', etc. actually increases the running speed of that program
on the CLR because it is able to skip some safety checks on the IL code when
it is executed; I don't know that the JVM does that, but it might be worth
looking into.

~~~
gdp
Most JVM implementations that I am aware of do sane things with respect to
optimisation of immutable values.

------
bkudria
What's so great about "Fluent" interfaces? If a language supports named
parameters, they're inappropriate, no?

(Yes, I know Java doesn't have named parameters, although it and many other
languages that don't have it have a work-around with assignment. this is a
general question.)

~~~
jrockway
Fluent interfaces suck. Mutating objects is not acceptable, especially when
you should pass the correct stuff to the constructor.

But this is Java, and it is the only way to cleanly allow inheritable
initargs.

(Perl/Moose and CLOS get this very right. I only use setters in those
languages in very, very rare occasions, and it is usually because I am hacking
around something messy.)

------
igorgue
Python is newer than Java? :D

~~~
tetha
In fact, Python appeared around 1991, while the official Java Programming
Language appeared around 1995 ;)

~~~
mahmud
But Python evolves fast! Every 3 years GvR finishes a chapter of SICP and
Python gets better.

------
_giu
" _The Java concurrency primitives like locks and synchronized have been
proven to be too low level and often to hard to use_ "

 _synchronized_ is not hard to use. it's rather not a good practice to use it,
since it will slow down code massively.

~~~
gdp
Concurrency in general is hard. You'll find that most uses of concurrency in
production systems is restricted to very specific patterns. This is probably
not a conscious decision, rather it's just very likely that straying too far
from very simple models of interaction between concurrent processes is
actually just beyond the intellectual scope of most people. I do concurrency
theory for a living, and concurrency primitives in Java still give me
nightmares.

~~~
uriel
Concurrency is hard only if you use the common 'pthread-like' model. There are
much better alternatives like Erlang and CSP (
<http://books.cat-v.org/computer-science/csp/> )

------
francoisdevlin
I think it's funny that this is right next to the interview with Rich Hickey
:)

~~~
fogus
If you look at the source for Clojure you'll see many (if not all) of these
techniques used throughout with an additional focus on static classes and
methods.

~~~
francoisdevlin
I guess what I was getting at is that _real_ next gen style uses the JVM, not
Java.

Down with Java, long live the JVM

~~~
coliveira
I don't see why people love the JVM if they don't like Java. I agree that it
is nice to have lots of libraries for free, but you also have the burden and
limitations of living with something that was created specifically for Java.
Languages such as Python and Ruby have been much more successful outside the
JVM.

~~~
mahmud
They love the JVM because it's everywhere they want their apps to be; ubiquity
has its own beauty.

------
tezza
final ... ah yes, the old final.

Just remember that _final_ is a signal to the compiler that it can perform
certain optimizations on your code. This includes inlining the value.

So if you use

    
    
      public static final KEY="value1";
    

you can get inconsistent class files if you change the value, the copy classes
that use KEY 'variable' across selectively.

This is most ant webapp and J2EE compiling workflows.

~~~
gdp
That sounds like really broken compiler or build script behaviour, rather than
something intrinsically wrong with the use of _final_.

~~~
tezza

      When the compiler sees a final method call it can 
      (at its discretion) skip the normal approach of inserting code 
    

<http://www.codeguru.com/java/tij/tij0071.shtml>

~~~
sovande
A final method is different from a final variable

------
gdp
Really good advice. Whenever I encounter Java code that employs some or more
of these techniques, I feel a little bit better about the world.

~~~
Retric
Are you joking? This advice is horrible.

He is advocating taking a verbose language and making it even more verbose and
far less efficient. Think about what the final in "public _final_ int x;"
means in #8.

Many Java developers have fallen for the idea that everything is an interface
to an interface. However, if you start by trying to get stuff done, you find a
most scaffolding is pure waste.

~~~
gdp
He is advocating using a style more like modern functional programming
languages such as ML, Haskell and F#.

The example in #8 is essentially recreating primitive tuple types present in
the languages I just mentioned. Given that the overheads on such an object are
small, and the garbage collector is good at dealing with short-lived objects,
it makes sense to instantiate a new class when it is necessary to mutate it.
Your optimiser will love you, and maintaining this style of code is
considerably easier.

~~~
Retric
Functional programming is ancient.

You might be all atwitter about the power of functional code. But, it's an
_old_ idea. Emulating the functional style a language that's not based on it
provides minimal gain, at the cost of code bloat.

PS: Pun was intended to be funny not mean. This really is an old idea, which
is occasionally useful, but mostly it's a waste of time, money, and CPU
cycles.

~~~
gdp
Sure, but I used the word _modern_. As in, "of the modern era". There are old
functional programming languages and there are young functional programming
languages. The fact is that most of the interesting research into programming
languages these days goes ends up in functional languages such as Haskell or
an ML-variant.

And I really don't buy your "bloat" claim. Surely mutating member variables
unnecessarily is "bloat". And having redundant getters and setters seems
pretty bloated to me. In fact, forcing everything in the universe into a
paradigm that largely consists of straight-line imperative code boxed up in
classes seems like the ultimate example of bloat, given that one could simply
code in an imperative style without using objects.

If anything, I would think that the measures suggested would result in
marginally _smaller_ code-size, which I assume is the metric you are employing
to measure "bloat". In performance terms, I would imagine that these
suggestions would result in no performance impact, or some small improvement
as it is quite likely that the optimiser will be able to do a better job if
you apply this style uniformly. As you say, it might be a _minimal_ gain, but
don't we as programmers have something of a responsibility to write the best
programs we can and use our tools to the fullest of our abilities, especially
when the cost is zero or almost-zero?

So what metric are you using here? I assume it's something a bit fuzzy like
"readability" or "ease of maintenance"? In that case, you're basically saying
"things that are different to what I already do are harder to do", which in
addition to being mildly silly, is a total cop-out and is intellectual
dishonesty. Too many good ideas in programming languages have been sunk by
programmers who hate the idea of not being the expert all of the time, with
such behaviour being hidden behind very weak justifications that sound
technical, but are actually just about egos.

Naturally, this might not be the case with you at all! However, I'd be very
interested to know on what objective basis you are making judgements about the
awfulness and bloatedness of code (in any language) that employs a more
"functional" style.

~~~
Retric
There is a reason that research into functional languages is limited to an old
or new functional language. Without syntax and compiler support you don't gain
any power to offset the limitations.

Anyway, the power of OOP is creating intelligent data. You can "automatically"
do things with a Point that you need to explicitly do with integers. If you
start dealing with a Fixed_Point objects, and Mobile_Point object, you now
have bloat with little gain. It's far better to have a "Final" flag on your
point, so it will toss an error when you try to change it vs. trying to
maintain 2 separate classes. That way if you suddenly need to change your
point you have to refractor less code.

Granted, if Java's foreach would automatically make helper threads to speed
things up then there would be an advantage. But, changing the form without
compiler support is pointless.

PS: Feel free to test your ideas, but allocating memory is still the enemy of
speed. When you create a temporary object outside of the stack it really does
slow things down.

~~~
KirinDave
I am glad to see someone else equally irritated by this "fashion statement"
that people engaging in, abusing their languages to ape other languages. Even
worse, most don't really understand the benefits of the languages they copy,
they pull the iconic cases and then pretend that languages aren't a teepee of
features that cannot stand when just a few poles are pulled in isolation.

~~~
gdp
Huh? Are you suggesting that people use functional programming languages such
as Haskell or ML because they are fashionable? Where on earth are you living
such that they are fashionable? I wanna live there.

~~~
KirinDave
Please reread what I said. The fashion statement is using a non-functional
language and adopting some functional mores.

~~~
gdp
I see. I'm still not sure how you justify your (revised) statement. What's
fashionable about it? You don't think people do stuff because they think it
makes them better programmers, rather than because of some perceived fashion
trend?

Similarly, you don't think the tendency for most non-functional languages to
adopt features and techniques from functional languages is because those ideas
are inherently valuable? Sometimes a good idea is a good idea, and I think
functional programming is an idea whose time has finally come. Maybe what
you're labeling "fashion" is actually just a natural progression towards
acceptance and adoption that started several decades ago.

Personally I think the trend towards selectively adopting functional features
(if there is one!) could only be positive. If more programmers become
comfortable with the concepts underpinning FP, then making the jump to using
plain ol' FP (rather than <insert your language here> with anonymous first-
class functions bolted on etc) will likely be much easier. Maybe it'll lead to
wide-spread adoption!

~~~
KirinDave
I did not revise my statement. You simply read it incorrectly.

To directly answer your question, I think that the merit of functional
programming techniques is in their application as a whole. Sniping high-
profile individual techniques does not bring a proportional benefit. It is
simply cargo culting. It is "fashionable" to mention "functional" programming
and to butcher the concept of referential transparency when writing code in
Java, C++ and C# these days. All it does is create a new style of obfuscation
for these languages.

