
Java for Everything (2014) - electrum
http://www.teamten.com/lawrence/writings/java-for-everything.html
======
AgentME
After working on large Javascript projects and running into and cleaning up
countless issues that static typing would solve, I've come around to being a
huge fan of static typing. Now, every line in an untyped codebase looks like a
potential typo or reference to an old function that was refactored ages ago
just waiting to blow up at runtime. Tests help, but only after you've written
them.

I really like Javascript, so I've been using Facebook's Flow type checker, and
it's been great. I was already using Babel (with Browserify), so nothing about
my build process even needed to change. It makes it easy to gradually add
type-safety to a codebase. It doesn't get in the way of common Javascript
patterns. Callbacks are still lightweight, but well-typed. I can still bypass
the type-safety and monkey-patch a property onto an object while I'm testing
something.

~~~
henryw
After coding for awhile now, I've also developed a penchant for statically
typed languages. I've been forcing myself to use TypeScript whenever coding
JavaScript for the static typing.

------
sebak
The article seems to be about Java vs Python. But it really only talks about
static vs dynamic typing. Not only has everything about that subject already
been said 1000 times. It's also not Java-specific. Java sucks IMO not because
of static typing, but because of the 'If you have a problem, add more
OOP'-mentality which has given us Java EE. About any argument he makes pro-
java is also valid for something like typescript. But with typescript you
still have the freedom of a scripting language for the parts where it makes
sense.

~~~
tomsmeding
Really good point. Replace every mention of Java in the post with any
statically typed language, and he definitely has a point. He doesn't argue
that Java doesn't suck.

------
smegel
> Sure you have to write: Map<String,User> userIdMap = new
> HashMap<String,User>(); instead of: userIdMap = {} but in the bigger scheme
> of things, is that so long?

More like user posts complex JSON object, which takes me seconds to parse into
a Python data structures, and hours or days to figure out complex mappings
into Java classes. It's often the mapping of objects to serialized forms is
where a huge amount of time gets spent in statically compiled languages. And
it's NOT just a once of investment - those mapping change in future and some
poor soul is going to have a fun time modifying your Java app, no matter how
well named your variables are.

If you are writing glue code or IO bound web servers without a high
performance requirement, the difference in productivity between Python and
Java is not at all trivial.

~~~
necubi
If you want type safety, you need to parse your JSON into a java class
(although "days" is definitely an exaggeration with the right tools—I'm a fan
of json-schemas and jsonschema2pojo [0]). But of course you don't get type
safety in python, so it's bit of an apples and oranges comparison.

If you're willing to settle for no type safety, there are untyped Java APIs
like Jackson's tree API [1] that are, while definitely more verbose than
Python's, similarly productive in my experience—and much, much faster.

[0] [http://www.jsonschema2pojo.org/](http://www.jsonschema2pojo.org/) [1]
[http://wiki.fasterxml.com/JacksonTreeModel](http://wiki.fasterxml.com/JacksonTreeModel)

------
HelloNurse
So you happened to work on stuff that Java is good for, including subjectively
good because you are familiar with Java and unfamiliar with Python (the web
app) and randomly good because mistakes were made in the Python implementation
but not in the Java implementation (the logcat tool), and you think this kind
of work is "everything" and you spit judgements about "dynamic languages".
Thank you for wasting my time.

------
bonobo3000
I like it! I have similar opinions on static vs. dynamic, Java vs Python or
PLs in general - too many judgements are based on shallow first impressions or
ease of getting started to the detriment of future maintenance.

Check out Scala :) Its a pretty complex language, but its the sweet spot
between Python and Java i've been looking for.

~~~
dvirsky
If you're looking for a sweet spot you should try Go.

~~~
lmm
Go is a bitter spot in my book. All of the costs of a good type system like
Scala's, but few of the benefits. (Go may well be better than Java, but why is
that your point of comparison?)

~~~
dvirsky
this thread is about java vs python. go to me is a sweet sport between what I
like about other strongly typed languages and what I like about python

~~~
lmm
The post you originally replied to was about Scala - if you're suggesting
people use Go instead, we should compare Go to Scala.

------
D15EA5E
> I realized that as I accumulate knowledge about 3rd party Java libraries and
> grow my own utility library, it becomes increasingly expensive to use any
> other language. I have to figure those things out again and write them
> again, instead of copying and pasting the code from the previous project.

Author is a douchebag

------
justsaysmthng
> The advantages of C and C++ ... don’t apply to my work. C# is nice but not
> cross-platform enough.

> Scala is too complex. And other languages like D and Go are too new to bet
> my work on.

So in the end you're talking about your work - the right language for the job.

Maybe Java is good for everything at your job, but not that good for most
things at mine.

I prefer C++ over Java every single time.

Not because of the more power that it gives me, but because I'm experienced
with it and I can get the job done.

I would use Javascript for a web application and Swift or Objective-C for an
iOS app. And I can't imagine doing that with Java.

~~~
hellofunk
Even for iOS I still greatly prefer C++ as well over Objective-C or Swift.

------
raptaml
You hit the spot with your article. I could not have said it better. Let's now
wait till the NodeJS/Mongo-webapp-in-2hours Kids ruling HN, start to "bash"
you to hell... But be sure: There are more than enough people out there who
exactly know what you are saying and why.

~~~
kzhahou
Nodejs is in decline here on HN, judging by post frequency.

------
jroseattle
> The big argument against Java is that it’s verbose.

I have a few others I'd prioritize over verbosity:

    
    
      - Generics
      - Dependency conflicts
      - Libraries that simply "fix" the language, i.e. Apache Commons, Google Guava
    

Disclaimer: your mileage may vary. This is simply my personal pet-peeve list.

~~~
reitanqild
Keeps getting better though, the example in the post:

Map<String,User> userIdMap = new HashMap<String,User>();

is now just:

Map<String,User> userIdMap = new HashMap<>();

and Java Generics already saves a ton of type casting as well as checks and
corrections IMO.

~~~
scalesolved
Or use Lombok and get it even more concise!

val userIdMap = new HashMap<String,User>();

------
tomohawk
The big pain point I see with languages such as Java is the deployment cost.
Since the runtime is separate, you have to deal with the cost of lugging that
around and installing it. When you have a larger scale system with lots of
different Java programs, you can run into cross dependency issues over time as
different programs require different versions of Java. Then there's also the
jar files and the rest of it. At the lower scale end, its a tough sell to have
to lug the jvm and a pile of jars over to a system just to run a single
program.

Python can have similar issues, even with virtualenv.

For this reason, I tend to use Go these days. It completely avoids this cost.
Also, unlike Java, any tools start up instantly and don't need to 'warm up'.

~~~
pjmlp
You can bundle a JRE with the application, no different than bundling libc.so
or mscvrt.dll along a dynamically linked C application.

Or just buy one of the many AOT compilers available.

------
draw_down
Why not do everything in C? The answer to that question is the answer to why
not do everything in Java.

~~~
catnaroek
With the “small” caveat that C's design tradeoffs don't make it as good a
general-purpose programming language as Java is, at least in 2016, no idea
about 1995.

Not that I think Java should be used for everything.

~~~
pjmlp
In 1993 I was using Turbo Pascal 6.0 for systems programming in MS-DOS.

Short list of TP 6.0 features in 1993!

\- Real type safe enumerations

\- Proper strings and vectors

\- modules (units)

\- Fast compilation (seconds)

\- OOP

\- Type safe reference parameters

\- inline assembler, naked functions, absolute addresses, pointer manipulation
functions, customizable memory allocator, overlays, procedure/function
variables for systems programming tasks

C++ was already picking up steam in Windows and Mac OSes and with CORBA and
DCOM for enterprise systems, the precursors to J2EE.

If it wasn't for the widespread of FOSS software based on UNIX and C culture,
C would have slowly faded out.

~~~
catnaroek
In 1993, I was just 5 years old, but, when I encountered Delphi, around 2000,
it was a very pleasant improvement over Microsoft's offerings:

(0) Compiler: Super-fast compilation times, unlike Visual C++; _and_ super-
fast generated executables, unlike Visual Basic.

(1) Libraries: Borland's VCL was vastly more sophisticated than either Visual
Basic's controls [underpowered toys] or Visual C++'s MFC [barely more usable
than the Windows API itself].

(2) Core language: Of course, from Pascal, Delphi inherited a real module
system [not C++'s `#ifndef` nonsense], real strings [not C++'s `std::string`,
let alone MFC's `CString` nonsense] and real dynamically allocated arrays [not
C's pointer nonsense, although C++'s templatized containers hadn't taken off
yet]. And Delphi's object system was something a normal human being could
actually hope to understand, unlike C++'s multiple virtual inheritance mess.

~~~
pjmlp
Yes, but then Borland had to screw it all up and now even the last compiler
developers that go all back to Delphi early days have left the company.

------
vardump
I can't use Java for most things I do. Can't create loadable libraries in Java
(.so, .dll, .dylib, etc.). Can't write kernel drivers in Java. Impractical for
most embedded applications.

Despite its many flaws, C/C++ is something you _can_ use everywhere. You can
write same piece of code to run on practically all possible platforms. Any
mobile device, desktop environment, microcontroller, it's even possible to
compile it to run on a web browser.

Writing libraries in Java has one gigantic flaw: those libraries can only be
used in JVM languages. Sure, you could use RPC or use JNI. But those solutions
are often completely impractical.

Edit: Fixed last sentence to be as originally intended, added word "often".

~~~
lmm
> Can't create loadable libraries in Java (.so, .dll, .dylib, etc.)

You can do loadable plugins in Java very nicely. If you're using Java for
everything then the calling code is also Java and it works great.

> Can't write kernel drivers in Java.

Not if you need them to run in-process in an existing non-Java kernel, no -
but that goes back to "use the same language for everything you do". (And IME
drivers rarely actually need to be in-kernel).

> Impractical for most embedded applications.

People told me this six years ago when I was developing for a low-power ARM,
and when I actually tried it I found it was complete nonsense - a lot of
embedded CPUs had more than enough power back then to run Java, and they've
only got faster since.

> Despite its many flaws, C/C++ is something you can use everywhere. You can
> write same piece of code to run on practically all possible platforms. Any
> mobile device, desktop environment, microcontroller, it's even possible to
> compile it to run on a web browser.

Sure, that's an advantage. But how often does it apply in practice? I'd far
rather have low-defect-rate code that I can run on the platforms I care about
than buggier code that can also run on some more obscure platforms.

> Sure, you could use RPC or use JNI. But those solutions are completely
> impractical.

Depends entirely on what you're doing. For many use cases they're perfectly
adequate.

~~~
vardump
> You can do loadable plugins in Java very nicely. If you're using Java for
> everything then the calling code is also Java and it works great.

JVM classloader based libraries generate a lock-in effect. Those libraries you
write are destined to be used almost exclusively from another JVM bytecode
blob.

> People told me this six years ago when I was developing for a low-power ARM,
> and when I actually tried it I found it was complete nonsense - a lot of
> embedded CPUs had more than enough power back then to run Java, and they've
> only got faster since.

I'd like to see how a Java based IRQ handler looks like. Or (gather/scatter)
DMA and memory mapped I/O. Can Java have same realtime characteristics AND
same or lower memory RAM/flash overhead as a C/C++ based solution? Cost per
unit matters.

> ...I'd far rather have low-defect-rate code that I can run on the platforms
> I care about than buggier code that can also run on some more obscure
> platforms.

This is why I have high hopes in Rust. If you can't run on those "obscure"
platforms you're required to run, then you need to write the code twice. How's
that a good thing?

>> Sure, you could use RPC or use JNI. But those solutions are completely
impractical.

> Depends entirely on what you're doing. For many use cases they're perfectly
> adequate.

Well, now you're not just shipping a 200 kB dll, but also a JVM bridge of some
sort (RPC or whatever), plus you need to vendor whole JRE in your installation
package. 100 MB+, much higher runtime memory consumption and debugging
challenges the bridge causes. How's this better?

~~~
lmm
> JVM classloader based libraries generate a lock-in effect. Those libraries
> you write are destined to be used almost exclusively from another JVM
> bytecode blob.

Sure, but it's the same for C, or any other platform. (I mean, many languages
have FFIs into C libraries, but they generally have APIs that are not at all
natural for that language).

> I'd like to see how a Java based IRQ handler looks like. Or (gather/scatter)
> DMA and memory mapped I/O. Can Java have same realtime characteristics AND
> same or lower memory RAM/flash overhead as a C/C++ based solution?

None of that sounds impossible, or even necessarily much harder than it is in
C. It won't look much like mainstream idiomatic Java, and it will involve a
lot more bookkeeping - but so would doing it in C.

> Cost per unit matters.

It does, but so do development time and defect rate.

> If you can't run on those "obscure" platforms you're required to run, then
> you need to write the code twice. How's that a good thing?

I'm not advocating writing the code twice. If your code needs to run on a
particular platform, you choose a language that you can find a way to make run
on that platform. It's just that in my experience of the business
circumstances (which are specific to my field, sure), "I might one day have to
port this to a platform that you can't run Java on" is a long long way down
the list of risk factors.

>Well, now you're not just shipping a 200 kB dll, but also a JVM bridge of
some sort (RPC or whatever), plus you need to vendor whole JRE in your
installation package. 100 MB+, much higher runtime memory consumption and
debugging challenges the bridge causes. How's this better?

Those aspects are not better, but they're often an insignificant cost compared
to the quality benefit you get from Java.

------
StreamBright
Funny how the author missing the point.

Few things:

\- you can write the example if, elif, etc. in any language that supports
pattern matching (dynamic or static) safely, it has nothing to do with type
systems at all

\- spinning up the JVM for CLI is still largely unsolved problem, this is why
Python or Go is used for CLIs more

\- verbosity does not matter? Seriously, the most annoying part of Java is
verbosity, that fosters a mindset that it does not matter how long is
something. In that verbose code we can hide few things: bugs and more bugs.

\- not knowing anything else than Java and Python, even in 2014 is silly

I think there are many better solutions for the problems he mentioned in the
article.

~~~
pjmlp
> spinning up the JVM for CLI is still largely unsolved problem

Only by those that ignore that there are quite a few Java AOT compilers to
native code available.

The OpenJDK isn't the only option out there.

~~~
StreamBright
Thanks for pointing out. I am going to check this option for my CLI projects.

------
devishard

        # Map from user ID to User object.
        userIdMap = {}
    

Or as I would write this:

    
    
        userIdsToUserObjects = {}
    

Ctrl + n in vim completes this easily, so I don't care how long the name is.

I agree about the general point of the article, being strong in one language,
but poor naming will bite you in any language. Comments are apologies for bad
code: only write comments when you can't write better code.

~~~
stickfigure
I split my time between Java and less-typed languages, and what always annoys
me is:

    
    
        messagesByUser = {}
    

Is the key a user id, username, a user object, some sort of stripped down user
hash, what? What about the messages? If you try to cram all this information
into the variable name then you've invented a perverse form of hungarian
notation. And of course you lose all that precious type information every time
you pass it off to a function.

Python is my go-to crutch for quickie projects that will never grow beyond a
few hundred lines of code. Anything more complicated needs a typechecker. I
only wish Java's was more robust.

~~~
aryamaan
What do you mean by more robust?

------
rohanprabhu
Huge fan of Java, and at my company we actually do end up using Java for
everything, but we are very cognizant of the fact that it is very specific to
us, our deployment and runtime infrastructure. This article feels extremely
opinionated and myopic to me. For instance,

> (python is) the wrong tool for code of any size written for pay, because
> you’re doing your employer a disservice

------
laichzeit0
Sounds like the author has never heard of or used Groovy before. There's very
little you have to write in "pure" Java.

~~~
vorg
The author wrote:

> For these scripts I decided to use JavaScript, primarily because it’s
> included in Java 6 and secondarily because many people know it

Apache Groovy isn't included in Java, and there's many incompatibilities
between it and Java (e.g. behavior of ==), so perhaps that's why it lost out
to Javascript for scripting.

------
TeeWEE

      The author should start writing a game in java.
    
      The author should start writing a heavy matrix calculations in java.
    
      The author should start implementing a small command-line tool ine java (grep?)
    

All these use-cases is where Java fails miserably. Pick to right tool for the
job. Is still the right answer.

~~~
wbillingsley
> The author should start writing a game in java.

Minecraft did alright...

~~~
andresmanz
It did alright on PC. The problem I see there is that they had to reimplement
it in C++/C# for other platforms, causing the updates to be way behind. Maybe
I got that one wrong, but wasn't there some announcement that they'd switch to
C++ in the PC version as well?

I'd like to add, though, that I don't generally see a problem with programming
games in Java. I just prefer C++ for that, with portability being only one of
the reasons.

~~~
aryamaan
In what ways cpp is portable and Java is not?

~~~
andresmanz
Usually, game consoles and handhelds don't have a JVM installed. I don't see
the point in porting (parts of) a JVM to these platforms for your games,
especially considering the little benefit (if any at all) that would offer.

~~~
nunobrito
Ironically to what you mention, Java was designed with embedded devices in
mind and particularly popular as game deployment platform for old phones.

Virtually any cheap phone (non-smartphone) comes with Java ME available.
Nowadays you find Android and the millions of Java-based games on the play
store.

------
igl
Java is the reason i stayed away from programming when i was a teenager.

Later I noticed that Java teams did not get things done quick.

My android phone stutters while playing music. (No it's not packed with apps,
there is at least 200mb RAM free)

------
nunobrito
I've been using Java since 2009 for everything from small projects to large
scale data handling (hundreds of terabytes).

Really, Java is just a tool. Language is familiar to anyone, performs good and
libraries exist for just about everything.

The only reason we don't use C is because we'd require end-users to correctly
pick different binaries and because the IDE for developing C is quite a pain
(don't want to start a fight here, it is just pain when compared to Java).

So, let the cool kids play with Ruby and Go. Some of us just need to get
things done.

~~~
tomsmeding
Does there exist "the IDE for C"? I know Eclipse for Java, but even that has a
number of competitors.

------
59nadir
If you're only going to use one language, I guess Java is a good candidate. I
don't see why you should be using only one language, though. Besides; if
you're only going for one language, I think there are better candidates than
Java that provide net wins on the whole.

------
thinkpad20
Reading this is frustrating because I agree with a lot of what the author is
saying (that using dynamic languages can speed up initial development but
incur future technical debt), but I think that Java has a huge number of
issues that prevent it from being a language I'd want to use for a lot of
tasks. Here are some examples, although since I haven't written Java in a
while I could be inaccurate on some of them:

\- the use of the Object type (surprisingly common)

\- No first-class functions or function types. New Java has lambdas but I'm
not sure if it has function types or the ability to pass a class or instance
method as a first-class value

\- No higher-order types (e.g. The type of a map function, let alone an fmap
function, can't be written)

\- Need for frequent casting is both inelegant and a big source of errors

\- Classes are giant, heavyweight and deeply stateful, and tend to have deeply
nested hierarchies

\- Class-scoped variable names (E.g. That don't require explicit 'this') are
confusing, and for example don't make it clear whether a variable being
referenced is a class variable, instance variable or local variable. Creating
inner classes complicates things further, and inherited variables and methods
are also opaque

\- creation of new types is a pain which promotes overuse of primitives
(ints/strings/bools) over more expressive and safe types

\- polymorphism via interfaces isn't particularly expressive, for example
AFAIK you can't make a function which takes two arguments of the same type
unless you specify that type precisely

\- null pointers are rampant, and even considered idiomatic, for example
during initialization

\- imperative style is forced on the user in a very strong way; for example no
literals for array lists, maps etc, standard library overwhelmingly provides
mutable data structures.

I could go on, but suffice it to say that the author's claim that the main
complaint against Java is its verbosity is a red herring.

It's also a bit disappointing to see him dismiss languages like Scala (and
presumably languages like Ocaml and Haskell, which he doesn't even mention)
due to being "complex", which suggests to me that he hasn't fully grasped his
own lesson that putting the time and effort into a safer, more expressive and
more strongly typed language is worth the initial trade off in productivity.
Although the author claims that once their code compiles it usually runs
without errors, this has definitely not been my experience. Indeed my biggest
argument against Java is that due to its imperative nature and inexpressive
type system, it's not _that_ much safer than many dynamic languages, which
makes it really hard for me to justify using it.

~~~
nunobrito
We had a large project that depended on a library written in Haskell. One day
the developer for that library quit his job. We sincerely couldn't find
another Haskell developer, had to re-write the library in Java.

Heck, I've tried hard to understand Haskell. Simply don't understand why
someone goes through the effort of using that exotic language. The old library
was taking 2 minutes to process input, the re-written version in Java took 3
seconds.

Just keep it simple, use Java.

~~~
catnaroek
There are very good reasons for using Java: portability, libraries and the
JVM's performance. But simplicity really isn't amongst them. Even
Featherweight Java (a carefully selected subset of Java for the purpose of
proving theorems about it) is full of tricky details.

That being said, yeah, Haskell's learning curve is quite steep, and writing
high-performance code in it is kind of a black art.

------
saheb37
don't you get tired of NPEs and checking everything with possibility that it
can be null? Scala solves it using Options.

There are lot more, but this is one which irritates me the most.

~~~
qw
Java 8 (or Guava for older versions) supports "Optional".

It is good practice for methods to return an Optional instead of null if you
can't guarantee a non null value.

------
davnn
It's apparent that a lot of developers have no idea of programming beyond OOP.
Multi-paradigm ideas and CTM especially don't seem to be widespread.

------
TheAndruu
Honestly, Java 8 has a ton of new features that give it a very functional feel
if one desires. Check out the new Stream api and map(), forEach() functions

------
testvega
nice article. I think you are on point and see the trend of java usage. Java
as a general purpose language. But cant never be compared in usage as C/C++.
May be in the near future Google Golang will be compared and competitive with
Java

------
xaduha
I'm not a fan of Java, but I am a fan ofJVM. You don't have to use Java to get
the most of JVM, you know. Especially since Kotlin is out, but it was true for
a long time with other languages.

------
danielalmeida
This has been posted before ("2014" in the title would be nice)
[https://news.ycombinator.com/item?id=8677556](https://news.ycombinator.com/item?id=8677556)

------
ljw1001
exactly

------
sklogic
What an idiot!

Different tasks require _different_ languages. It's not possible to pick just
one. Most people gave this moron the right answer, and yet he failed to
comprehend it.

And this pathetic cretin clearly never ever seen a truly expressive language.
Likely, he never seen anything besides his pathetic Java and stupid Python.

