In the case of Java it is not that Java is a "large language", it is that to get anything useful done with Java you need to know about Maven and Spring and Log4J and Apache Commons Logging and SLF4J (because if you're using a lot of libraries surely all of those will be in use.)
That is, it is the complexity of the ecosystem, not of the language.
Yes, it's a problem I call the Java Jungle - and it's something that happens (and will happen) to every successful language, I believe. Therefore it's not enough to ditch it and start again - devs need to figure out how to manage complex communities and library/architecture options. Although I'm not entirely convinced Java is going to be the one that really figures it out.
It's probably Node or Go or Rust that will finally get it right (they already get it right tacitly acknowledging that it's okay to couple to linux, therefore it's okay to be native, and that the correct unit of deployment is the whole damn server image.)
When I was learning Java recently in anticipation of a job programming Java - I was surprised by this reality. The core of Java is remarkably simple to learn - there's not really all that much to it.
The complexity is indeed in all of the libraries and build frameworks and well intentioned but silly HammerFactoryFactoryFactoryFactories.
I think the case can be made that Java was too simple. It's inability to express very much within itself is what led to explosion of external tools to make it "better", or indeed, "work".
I think it was deliberately designed as a simple language to be used by large groups of people in simple ways, but actually failed so epically at that goal because of being too simple that it actually destroyed the entire idea of building a language deliberately for large corporate use. (Note that it has grown a lot since then; it had to.) Go's the first language I've seen since Java try for that niche. I've said it before: In the short term Go may be stealing from Python and Node, but in the long term, Java's the one that needs to be worried about Go.
> I think the case can be made that Java was too simple. It's inability to express very much within itself is what led to explosion of external tools to make it "better", or indeed, "work".
Yes, Java (IIRC) originally aspired to be a small, simple language with a few and honest constructs that everyone would understand and use. Of course—speaking of CL!—this is Greenspun's Tenth Law at work. To be fair, that's not necessarily to say that blowing the syntactic budget on a for construct is a good decision, and there are very good reasons to let language design take place in a marketplace of extensions rather than in a centrally-mandated core language. But if the idea is that if you mandate a simple language then the language as people use it will necessarily be simple and uniform, then no.
(Doing my crazy-man turn for moment: this is just one manifestation of a much wider problem. The idea that pushing unavoidable but unwelcome complexity (or unreliability or untrustworthiness, or things like only-partial support for interfaces) in-band is equivalent to making it somehow go away is the great all-pervading madness that afflicts computing. "As simple as possible, but no simpler"...)
> In the short term Go may be stealing from Python and Node, but in the long term
Go is a niche language.As a niche language it will perform well in its niche, but it will never be as big as Java or C#. Go total lack of expressiveness makes it unfit for a wide range of applications.
Java is rigid, but I think version 8 makes it more enjoyable. But it will not make all the terrible java core apis and framework go away.They are still here.
I think this is a very fair way to characterize Java's problems. The syntax is annoying but generally let's you get tons of shit done in a reasonable matter. It lacks the features of a stronger type system like Haskell or Scala, but you can get pretty far.
The ecosystem on the other hand can be totally befuddling, maven, gradle, the dozen or so DI frameworks and the various codebases that seem to use all of them, choosing between Apache or Google Java libs (or both!), etc.
Scala on the other hand suffers from an explosion of language features that means you either get a ton of shit done because you love Scala or you get nothing done. I'm not sure which is better anymore since I work in both on a daily basis but it's a different tradeoff.
That's a matter of perspective no? I'm not fond of symbols so reading Ruby super-terse code makes me choose watching a movie on Netflix over that.
> The ecosystem on the other hand can be totally befuddling
You mean slightly better than Python that keeps re-inventing the (half) wheel? :D
Maven is used by the majority projects with Android projects as an exception because Google pushed hard for Gradle.
For DI frameworks: Spring is the majority winner with Guice/CDI on the second place.
Apache vs Google Guava only because Guava came in late and both are just a nice small library (not a framework). Older code within the codebase might have already used Apache Common lib and newer code within the _same_ codebase will more likely use Guava where it is fit (I/O is an area where Apache has better library).
We should also compare this situation with various Auth & Auth lib for Rails/NodeJS project :).
So shrug ... Java has been around longer, at most usually there are 2 competing libraries for certain area and the better ones tend to win (again, depend on your perspective what "better" means: some prefer Maven over Gradle).
> Scala on the other hand suffers from an explosion of language features
This isn't what I feel. Scala's feature set is small, but powerful.
Some examples:
- Scala has no notion of static methods, unlike Java. Every reference or value is an object, every function call is a method call, with Scala's OOP being much, much closer to Smalltalk than any of the C++ inspired bastardizations tend to be
- Scala doesn't have special syntax for certain types, like Java's plus operator for Strings
- Scala's support for variance is much simpler and at the same time more powerful than Java's use-site variance by means of wildcards (I've met no Java developer that can tame Java's wildcards, I'm sure they are out there, I just haven't met them)
- speaking of variance, Scala's type-system has Null and Nothing and AnyVal and Unit; in Java you've got "void" as a special construct, in Java the primitives are special, in Java "null" has special and unexplained treatment, in Java Nothing is surely there somewhere in the implementation, but you can't use it ;-)
- Scala-async is a library, instead of a language feature like in C#
- Slick is a library, instead of a language feature like Linq in C#
- Scala's for comprehensions are much more general purpose than the foreach construct in Java, or than for comprehensions in Python, which means that Scala doesn't need new constructs for dealing with async stuff or with (god forbid) monads
- Scala's traits are much better and I might say easier to understand than Java 8's default interface methods
- Scala does not have side-effecting keywords such as break or continue
- Scala does not have the special indexing syntax of arrays
- Scala does not have special syntax for building arrays or maps, as the basic language is enough for doing that in an expressive way
- Scala does not have operator overloading, or operators for that matter; as in Scala the operators are just plain methods
And then indeed, we can talk about things like pattern matching or case classes, which in my opinion add tremendous value. But you know, static languages need features in order to be usable / expressive and cannot be minimal in the way that Scheme or Smalltalk are. For example people complain about implicit parameters, however implicit parameters happen anyway in any language (e.g. undocumented dependencies, singletons) and at the very least in Scala you can document those dependencies in the function's or the constructor's signature and have it statically type-checked and overridable. Plus implicit parameters allow one to work with type-classes and compared to Haskell, in Scala a type-class is just a plain interface and its implementation is just a value. And also the CanBuildFrom pattern is not a type-class and isn't possible in Haskell. So such a small feature such as implicit parameters yields tremendous power.
I could probably go on, just wanted to point out that Java's simplicity and at the same time Scala's complexity is entirely misleading. And also, I happened to introduce many rookies to Scala and by far the biggest hurdles are posed by exposure to new concepts or design patterns, brought by functional programming of course. Even explaining Future is problematic, a standard library thing that otherwise leaked into Java and many other languages as well.
I would agree with you, except there's no way to fit type erasure into that sentiment. Type erasure is a complex solution to an easy problem, done purely out of laziness and a broken sense of what "backwards compatible" should mean. The moment you try to do anything "interesting" with generics, you realize the sham that they are and start passing around `Class<T>`, which is exactly what you would have done before generics anyway.
NodeJS tries to be as simple as possible but at the end of the day, you need to use/download/learn libraries with different quality/documentation level and different API-feel/code-style.
Java libraries tend to have "magic" that alters the language semantics. E.g. Spring's dependency injection breaks your reasoning about how an object is constructed. Hibernate breaks your reasoning about when object fields can change. Tapestry breaks your reasoning about basically everything. There's a difference between a library that follows the rules of the language and a framework that changes them.
(admittedly to a certain extent I've heard the same said of rails)
Except it isn't. Attributes of languages include their documentation syntax and extension API. Getting this right makes a remarkable difference for how easily a person can grok a new library or extension and make it useful. A good language has a common "language" overall, not just code syntax.
That may have used to be true, but with every release of Java the language and standard library grows. More features means simplicity is lost, and Java is huge.
The language hasn't changed very much since inception. Java 8 was probably the biggest of the changes with Lambdas. But even so Java 8 looks a lot like Java 1 at the language level.
The standard library has always been bloated. Hopefully Java 9 and Project Jigsaw will break it up into smaller manageable trunks. Really a lot of it needs to be burned away for new stuff to grow.
The tough part for Java will be when they have to break backwards compatibility to move the language and VM forward. If not done careful they will have another Python 3 on their hands.
That is, it is the complexity of the ecosystem, not of the language.