Java's Cover (2001)
paulgraham.com
paulgraham.com
> I've never written a Java program, never more than glanced over reference books about it, but I have a hunch that it won't be a very successful language.
Given that Java became spectacularly successful and still is, the question is why the author turned out to be so wrong? My guess would be that the author thinks the people he know (apparently all extremely competent "hackers" with great taste) is the kind of people who decide what becomes popular in the industry at large. We all live in our own bubbles.
I think the bubble of the author becomes apparent when he mentions Perl positively compared to Java. Sure, Perl is fun, edgy, powerful in weird ways, the opposite of Java in any way. But if I had to maintain complex code written by someone else, I would far prefer to maintain Java to Perl. I suspect the author is the kind of developer which never have to maintain code written by other programmers.
Also, this is not serious analysis, he twists motivations and reasons for certain Java decisions. He does not look at advantages and disadvantages to evaluate the language. Instead, he looks at how he can twist anything at had as inferiority. Note also how insulting the article is towards both original authors and "them, not real hackers using Java".
1. IDE. When Eclipse was released back in the early 2000's, it was an amazingly productive tool. Refactoring is a one or two keystrokes away. Java's simple yet mostly sufficient type system allows us to jump around definitions, references, usages, and declarations easily. The built-in compiler of Eclipse allows really accurate auto completions. I could easily learn a new code base by walking through the code with a debugger while jumping around the source code by semantics.
2. Standards. First its servlet, but soon web containers. Even in its early days, such standard made it much easier to write web applications. Engineers just needed to remember a few simple rules before producing concurrent web services.
3. JVM and all the toolchains. All the jconsole, jstack, jmap, gc logs, etc and etc. They may be norm now, but when they were productivity boosters when they first came out.
4. Java's standard libraries, especially the concurrency libraries. All those containers and high-level synchronizers are so much easier than the vanila mutex. This is something I don't quite understand about the Go community: why are people fine with using Mutex everywhere?
5. All kinds of JSRs, such as JAX-RS. You may hate them personally and passionately, but they do provide easy enough APIs and most importantly a standard for all kinds of frameworks to support. A Java programmer can easily switch from one framework to another without much learning curve.
I wonder how much Java success in early 2000's was related exclusive to this. I remember asking Java programmers why they liked it so much and all they talked was about IDE features and not the language itself. It looked like some couldn't even tell the difference between an IDE and a programming language.
I mean, this is why languages like Lisp and Smalltalk have such devoted fans...
Purists may scoff (pretty sure I did back then too), but now I think this is the ultimate compliment.
Why is it amazing? Java was a well-compromised piece of PLT design, by a geek friendly company known for its engineering chops, with a very cool (hackable!) VM that allowed for both compiletime and runtime magic, and all this over and above the fairly well equipped standard library. (Beyond that, concerted Java hype in late 90s was ~same as what we saw later with RoR, Scala, Go, and now apparently Rust. Java may not be cool these days but it was the shiny thing in late 90s.)
The default approach in Go is to use channels. The preferred idiom is "share by communicating". I think mutexes are overused by people who came from other languages and who aren't accustomed to channels yet. They spawn goroutines which communicate by sharing when it should be the other away around - no shared state with a few exceptions. I think there's no proliferation of synchronization primitives in Go because sharing state is considered a bad practice.
We aren't - we're using channels :)
I remember getting into an argument with two guys in the men's room in Center Ithaca circa 1995, they thought Java was overhyped, I thought it was going to to be big.
I was right, with the caveat that the original "applet" use case where you wrote little GUI apps to run in a rectangle in a web browser turned out to be a complete wash.
in a funny way, the jvm hitting android made it the networked desktop of the world, but in no way sun/oracle predicted it :)
Java more or less got "write once, run anywhere" working, I'll give them that (although I still see programs that e.g. use a hardcoded path separator, they're the exception rather than the rule). But it's hard to see anything that it really delivered on in terms of working better than e.g. OCaml.
> Easy code reuse?
Yes, as proven by rally large ecosystem of libraries and frameworks. All of that is literally code reuse.
> Low code development by using XML? No.
This was NOT original promiss at all. Again, these were first attempt at creating larger frameworks.
> Not needing generics? No. Checked exceptions being a good idea? No.
What are you talking about here? And yes both generics and checked exceptions have their use and dont make creating or maintennance of software hard at all.
It was absolutely something that was claimed at the time. Java's JIT, good as it is, has not lived up to the hype, to the point that newer languages (and even newer versions of Java itself) are moving away from it.
> This was NOT original promiss at all. Again, these were first attempt at creating larger frameworks.
It was absolutely something that was advertised by Spring and by Java EE, and didn't pan out.
> What are you talking about here? And yes both generics and checked exceptions have their use and dont make creating or maintennance of software hard at all.
The original Java claimed that a feature like C++ templating was not needed, which proved to be false. Checked exceptions are widely regarded as a failure; no major new language (even on the JVM) uses them.
Generics are nowhere near to being similar to C++ templating. Also, I never understood hate of checked exceptions that invariably comes from people who dont use Java. They don't bother much and have their place.
There was no major hype about Java being faster then C or C++ in its origin. They quite explicitly talked about sacrificing speed for other properties. Java however got faster in later developments.
They were advertising the same thing that modern low-code proponents are: the idea that you'd be able to change your application's behaviour by changing a configuration file, and that this would be superior to editing code. That was definitely part of the Java marketing.
> Generics are nowhere near to being similar to C++ templating.
Lol what. They use the same syntax and provide (not all of, but most of) the same functionality.
> Also, I never understood hate of checked exceptions that invariably comes from people who dont use Java. They don't bother much and have their place.
I do use Java, I still hate them. They're very cumbersome, and again, the bottom line is: twenty years on no other language wants them, not even the likes of Kotlin.
> There was no major hype about Java being faster then C or C++ in its origin.
There absolutely was. The Java JIT was hugely hyped at the time, and there were even benchmarks showing it outperforming C on particular problems.
To be sure, that is configuration, though.
Spring is definitely a 3rd-party library builder, and I'm unaware of promises like that from Java EE. Can you help me understand what informs your view on that? It seems like they delivered a bunch of stuff that made it easy to consume XML for all kinds of questionable as well as reasonable purposes, but it was Spring not Java trying to turn XML into a scripting language.
Why couldn’t you? There was always an escape hatch API that let’s you manage that few direct pointer accesses mandated by hardware - otherwise the rest could very well be written in a managed language (as shown by research done by Microsoft for example)
It is hard to argue against the Java ecosystem of libraries.
I use forward-slash (/) on Windows and OSX/Linux, and the JVM/libraries do the right thing all day. Please enjoy.
The approach he took in forming the opinion comes across as quite arrogant and error-prone.
""The good languages have been those that were designed for their own creators: C, Perl, Smalltalk, Lisp.""
is a fair comment.
To say that these are the good languages is hubris.
This comment didn't age well.
What the statement doesn't do is support the opinion that Java will be unpopular for being a bad language.
The thing that made Java succeed was the write-once-run-everywhere JVM and the huge effort spent by Sun, IBM, and others to make the JVM as good as it is.
I find this interesting because it's the first heuristic I use to judge anything new, technical or otherwise (e.g. TV shows or games). Did someone pay to put it in front of me?
It turns out to be a mostly true assumption that you'll hear about good things organically.
I'll readily judge a new programming language or library based on the quality of its presentation, because if no thought is being given to presentation, I can tell already that it's not going to get much traction. And if a PL doesn't get much traction, its ecosystem and even its long-term development will likely suffer.
Although- that's really just a minimum bar, and I agree with the author that Java went way way beyond that, and had more money tied up in that than felt warranted, so I probably would have had the same feelings
At one end of the scale for me is Rust. I discovered it through organic hype and I like the language but it's not successful enough for me to have found a job writing Rust.
At the other end is TikTok. I saw many ads for it before anyone I know ever talked about it. It's massively successful but it doesn't appeal to me in the slightest.
Java's Cover - https://news.ycombinator.com/item?id=21558053 - Nov 2019 (21 comments)
Java's Cover (2001) - https://news.ycombinator.com/item?id=10761400 - Dec 2015 (40 comments)
Java's Cover (April 2001) - https://news.ycombinator.com/item?id=4504375 - Sept 2012 (180 comments)
JAVA's Cover - https://news.ycombinator.com/item?id=3837711 - April 2012 (2 comments)
Java's cover (2001) - https://news.ycombinator.com/item?id=1182743 - March 2010 (2 comments)
Every LISP codebase is different, the language is famous for making your own „DSL“s. Every Spring Boot codebase is similar. One of those approaches doesn’t scale in terms of collaborators.
Not sure choosing the “wrong” programming language can kill a startup just like the lack of traction and sales.
""" ...
7. It's bureaucratic. ...
...
9. It's designed for large organizations. ...
...
10. The wrong people like it. ...
...
"""
These might all be shades of the same underlying cause but, for me, this is exactly why Java has "failed" in many domains and "succeeded" in others. Precisely because it was marketed as boring technology that large organizations could use is the roots of it's success in business domains and it's failure in "hacker" domains.
Daniel Sockwell had a talk about the "Ideal Language for Writing Free Software" [0] and many of the points are mirrored about what makes a language well suited to an individual maintainer of a FOSS project that allow them to use its high skill ceiling and the programmers deep knowledge of the language are the things that business interests select against to allow for programmer fungibility.
Paul Graham is a great writer, and a horrible technologist.
https://www.cs.tufts.edu/~nr/cs257/archive/bill-pugh/jmm2.pd...
most other programming languages make excuses. Build system with dependency resolution that works (unlike Python) IDEs take advantage of static nature of language. Static nature of language enables refactoring.
Lambda syntax that's probably more concise than your favorite language. Implementation of Lambdas that meshes perfectly with existing practices in Java. All-virtual polymorphism is one of many ways that Java doesn't steal IQ points from you the way C#, C++ and languages like that do.
Thing is, they turned it around.
Some APIs were excessively verbose due to the lack of lambdas, which were emulated using anonymous inner classes.
If you have a link, please share.
Gosling say closures represent the realization of a dream that was postponed in Java's early days and resulted in the invention of inner classes - "an uncomfortable compromise" that failed to provide the desired level of simplification. He notes criticism that closures are too complex, but advises people to read "through all of what Neal has written".
Java is mostly about interfaces. Classes are just a way to implement them. This is one of the differences between Java and C/C++.
The way lambdas bind to SAM interfaces and implement them is pretty different than say scala or even C/C++ function pointers where the necessary parameter/return type can be encoded into a variables type and referred to directly.
I think that's cool enough but one of the subtle elements of design brilliance was how local variables must be final to be bound into a closure. There's a whole class of ambiguity removed and static guarantees in the face of concurrency that I think goes unappreciated.
I'll have to mull over that. I guess to me they seem aligned enough, thats why it feels so elegant. Or maybe I haven't thought about it enough.
> rather compiled as static functions and an invokedynamic instruction that will resolve to them at first occurrence
Yea! but that invokedynamic calls the lambda metafactory which spins up bytecode for a class with 2 things: a) a constructor to bind the values captured from the scope the lambda was declared in to fields, and b) an instance method that feeds those fields to the static function you referred to.
I'd argue that that class is essentially an anonymous class. Maybe I'm easily impressed, but that functional programming <-> OOP duality of lambdas/closures and SAM interfaces always felt profound.
We can get along! There's no need for this feud!
This library contains a huge number of Iterables, each of which has at least one Iterator implementation.
https://github.com/paulhoule/pidove
It is convenient to let the Iterator be immutable and the Iterator be an inner class that gets its configuration information out of the Iterable.
(That said, if people really thought seriously about Iterator being a Supplier<Iterable> people might think more rationally about error handling. Also in a slightly parallel universe the Iterator would only have one method since remove() hardly ever gets used and having both hasNext() and next() methods is asking for bugs.)
This is how things like Babashka (Clojure CLI scripting runtime) are possible [0]
It's even possible to compile it ahead of time, making projects like a Clojure CLI scripting runtime with almost instant startup time possible (babashka).
huh, that's a big statement.
I used to love java... I could write pretty much anything with it.
Websites? sure, there's a ton of stuff for that.
Command line programs? that's the basic.
GUI programs? pick between awt, swing and swt... and there was qt-jambi too!
server programs? no problem.
mobile apps? J2ME is nice!
That was ~15 years ago... to say no one loved it seems a bit dumb, frankly.
Myself I do not like Java at all. But I like this article even less.