As a replacement for Java, Scala is a failure. It is a language too complex that doesn't provide enough benefits for people that just want something better than Java.
The perfect Java replacement would have - local type inference, less verbosity (e.g. public by default), full closures, anonymous blocks, no generics, special syntax for arrays and hashes, operator overloading and the ability of a variable to behave as if dynamic (e.g. leveraging the future InvokeDynamic). I would also completely purge checked exceptions and also get rid of the general syntax for anonymous classes - basically get rid of anything not useful.
People actually liked earlier versions of Java. It was a simple language, while still a lot more productive than C++. They fucked up its evolution and IMHO it's pretty sad that people like Scala so much; it just shows how low are the standards.
"less verbosity (e.g. public by default)". That's Scala. def myMethod(arg:Int=1, arg:String="myDefaultValue") ... with no boilerplate crap.
"full closures". That's Scala. val myImmutable = { runThisCode }
"anonymous blocks". That's Scala.
"no generics". That's-- more or less Scala.
"special syntax for arrays and hashes". That's Scala.
"operator overloading". That's Scala.
"the ability of a variable to behave as if dynamic". That's Scala.
"I would also completely purge checked exceptions". Scala, so long as you stop writing try catch blocks.
"and also get rid of the general syntax for anonymous classes". Scala.
Look, I just recently rewrote a ten-thousand-line Java web app into Scala. I got-- no joke-- 75% code reduction, and the only reason I didn't get more was due to the fact that I decided to stick with Struts2 instead of moving to Lift.
Think of your typical method that accesses a Hibernate named query, and returns a boolean as to whether or not that item exists.
You made more or less my point -- but my point was that Scala provides too much; and I don't want to choose a subset, as my subset will be different than yours.
Also, I would like a language that's as close to the JVM type system as possible, yielding the same performance as Java in all instances (including on Android, where Dalvik doesn't have the same GC and optimization characteristics).
"no generics". That's-- more or less Scala.
Generics are an inherent part of what Scala is. Surely it takes care of some gotchas, but I see many code samples where I feel like puking.
Generics weren't really meant for languages without Hindley-Milner.
"the ability of a variable to behave as if dynamic".
That's Scala.
Scala is not dynamic by any stretch of imagination, no matter how much wishful thinking you can incur because it has structural typing -- I see this notion flying by all the time, but people generally don't know what they are talking about.
E.g. you don't see people saying this same thing about Haskell, when compared to Lisp, even if Haskell is even more concise than Scala, taking structural typing to extremes.
What I mean was that I'd like something like the dynamic types in C#.
"You made more or less my point -- but my point was that Scala provides too much; and I don't want to choose a subset, as my subset will be different than yours."
Sorry, but that's the most ass-backwards point I've heard. The language provides too much power and flexibility, and you want to be locked into one specific format, syntax, and the subsequent reinventing-the-wheel nightmare that causes most projects to go horribly over time, budget, and stress levels?
Um, I think you might be over-attributing language features to project failure, there.
The language subsetting issue is a huge problem, c.f. C++. The complexity of Scala makes it very difficult to understand a lot of library code, even if you're quite competent in it. To keep code for a large code base manageable and understandable, most companies will end up defining the "allowed Scala" in a coding standard. This is a failure of the language, IMO.
I was going to say the same thing. I've been using Scala as a "better Java" for a while now, and the argument that Scala is too complex is kind of baffling.
Take your Java code, remove almost all the type info, and add some nice syntactic sugar for singletons. That's beginner Scala, and it's already worth using. The rest of the language is just gravy.
Unfortunately I think you're right that Scala is too complex to displace Java. If you're looking for a functional language you can use to to real work though, Scala is just the ticket and it's really not that complex once you start using it. None of the above-average programmers I've worked with would have any trouble picking it up with a little motivation.
Personally I find myself much more productive in Scala for anything non-trivial than in any other language.
You forgot "fast". The perfect Java replacement would also have to be as fast as Java. Groovy, Jython, allow you to program on the JVM more easily, but unfortunately run much slower than Java. One major benefit of Scala is that it runs at pretty much the same speed as Java.
> The perfect Java replacement would have - local type inference, less verbosity (e.g. public by default), full closures, anonymous blocks, no generics, special syntax for arrays and hashes, operator overloading and the ability of a variable to behave as if dynamic (e.g. leveraging the future InvokeDynamic). I would also completely purge checked exceptions and also get rid of the general syntax for anonymous classes - basically get rid of anything not useful.
The #1 feature of Groovy in my mind is that there is almost no learning curve whatsoever. All Java code is already Groovy code - you can learn all the dynamic tricks as you go.
Scala introduces new versions of collections like Map and List that aren't compatible with Java's versions. The syntactic sugar only works with the Scala Maps.
Luckily, in Scala there's a JavaConversions package that allows you to cast back and forth from Maps, Lists, Sets, etc, to whatever Scala type you want.
And that language (mod unlimited operator overloading, but allowing things like comparison operators to work on comparable objects, and having simplified generics rather than no generics) is... Gosu: http://gosu-lang.org
all we need is C# 4.0 running on JVM. And instead of no generics, substitute generics implemented as they are on the CLR.
Done! no incoherent Scala to learn. I have no complaints about C# except that it exists on MS island, instead of running on JVM in the Java ecosystem. As language, I cannot complain about C#. I have found clojure to be very easy to learn and use recently, but I must honestly admit that if it didn't exist I would never have noticed if C# were on the JVM.
I can complain about C#. The type inference is artificially limited which forces you to write types everywhere. There is no way to define an interface on types which are not under your control. Generics are missing a number of features that would be extremely useful, like defining a parameterized type with a constraint on the parameter type's constructor. Metaprogramming is limited to treating lambdas as expression trees and has no syntactic sugar. There is no facility for destructuring function arguments or doing pattern matching. Events and properties are not first-class constructs that can be passed around, which limits composability. Tuples have no syntactic sugar associated with them so they look super ugly. Et cetera, et cetera, et cetera.
It severely beats Java, but it falls pretty far short of Clojure, in my opinion.
Can someone please explain to me why Scala has been getting such vitriol on HN comments lately? I've never found Scala "difficult"; you can use Java and take in new bits as you go. Why do people keep saying its too complex? It's no more or less complex than Ruby, and certainly less of a learning curve than Haskell, more familiar syntax than Lisp (for more programmers), yet the comments here indicate that "Oh, Scala is so complicated, how could anyone learn it?" This article seemed on the money for me.
I know things like type erasure and other programming language bits and bobs upset the PLs gurus, but I really don't care about that. I can write concise code that looks like a dynamic language, but get full static type-checking. That's a huge win.
I can't explain vitriol, but when I took a brief look at scala it seemed to have unnecessary complexity from a bunch of ad-hoc rules to simplify some specific case. Little things, mostly syntax, like the conditions for leaving out parentheses in a function call, or around a tuple, or braces around a function body. If there's a unifying explanation for all the syntactic abbreviations, it wasn't in Odersky's book. Some of the conditions for traits and implicits look fairly ad-hoc, but at least you can guess they conservatively ensuring some simple essential propertly like decidable implicit inference.
It so happens I've been trying to write my first "real" Scala application these past few days. It's been a harrowing experience. Just a few highlights off the top of my head:
* Eclipse support is spotty. Apparently legal programs suddenly develop lots of errors. Sometimes restarting Eclipse will allow the program to run anyway.
* Types are constantly getting in my way. Sometimes types are correctly inferred, sometimes I need to add types to hint the compiler about what I'm doing.
* Writing anonymous functions remains hit and miss. I just throw in underscores at random until something works.
* I don't understand where the round or squiggly parentheses go in for comprehensions; i.e. what goes in the parens and what stays outside.
* Hashmaps have a cool "+=" operator to add a key-value pair. So why does "put" work but "+=" doesn't? Another mystery.
* Sometimes the parentheses after function invocations are optional if there are no parameters. Sometimes not. Why?
It's not Scala's fault that the Eclipse plugin is less than perfect, it's already very powerful. As for my little struggles with the language, none of this is witchcraft; I'm sure there are well-defined rules and sensible answers to all these questions and many more. But I must say I'm annoyed with the huge number of rules behind Scala. The amount of stuff I need to learn to really use Scala effectively is daunting.
Contrast this with my Ruby experience. This is a language that places great value on orthogonality: wherever possible, every operation works the same in every situation. So you have a smallish number of versatile functions, not too much stuff to absorb and things generally Just Work (TM). I taught myself Ruby and Rails and wrote my first useful Web app in a couple of weeks' worth of evenings, and it was a very pleasant experience.
Clojure, similarly. All the parentheses took some getting used to, but the language's syntax is wonderfully simple and consistent, so getting stuff done is mostly just a matter of looking up the most appropriate function in the cheat sheet. I managed to be productive (for small programs) with Clojure in a couple of days.
Scala is no doubt a fantastic language. But thanks to its kitchen sink attitude, it's not an easy language to come to grips with for someone with an aging memory and a less than full-time commitment.
But thanks to its kitchen sink attitude, it's not an easy language to come to grips with for someone with an aging memory and a less than full-time commitment.
Perhaps this is one of the things that is tripping people up that I'm not doing. I tend to still be quite verbose in my code, even if only as a way of reminding myself what I thought the code was supposed to do (ever look back at Python and you're not really sure whether the variable is supposed to be a list or a tuple or a string? I have that problem all the time). I don't tend to use all the flourishes like underscores and such.
It seems a bit like Perl's many ways to do it attitude. Except I feel like Perl was designed by ideology, whereas Scala has a lot of bits and pieces because it wasn't clear to Odersky et al. which bits people would like and which they wouldn't. Perhaps rather than trying to enforce an idomatic style, they wanted programmers to find their own way. But that means there's things in the language that exist and can't be taken out (XML literals), and there's no documentation cohesion (by which I mean different documents will tell you to do different things, and you're not sure which is best).
If you Google "effective scala", you'll see a number of people clamoring for a book along the lines of Effective Java, and Scala sorely needs it, but Scala is still too much of a moving target to warrant putting anything in dead tree form yet. The Davetron Scala Style guide, however, is a really good stop gap, and helped me a lot.
Programming in Scala has a very straightforward explanation of for comprehensions. Mysteriously, almost every other explanation I read left me more confused than before. I don't know why there are so many poor and/or partial explanations out there. Read Programming in Scala instead and you'll be fine.
As for type inference, another week of programming and you'll fall into a groove where you're anticipating when you need to declare types and when you don't. I had the same pain, and after a week, it had dropped down to a very occasional annoyance. It might just be my programming style, though -- I declare the return types on all functions that are meant to be called from another class or object, so there's a lot of information for the compiler to work with.
I agree about the underscore thing. It's pretty useless, and Clojure's version looks superior to me. As best as I can tell, the underscore doesn't work inside an extra layer of parens or curly braces. But it's just syntactic sugar, after all. Using a named variable isn't the end of the world. It's just three extra non-whitespace characters, "n =>".
> using the word complex, unnatural, academic, “your world” or unintuitive to mean “I am not able nor am I willing to invest the effort to come to to understand this.”
Other than those people:
The blog author I quote above is one of the many "PL gurus" you speak of that rip into Scala because of its various deficiencies when compared to the likes of Haskell. The ones I am smart enough to understand mostly revolve around the type inference and type erasure problems. You mentioned those but I have already run into issues where I did care about them so I don't think its fair to dismiss them as you did.
The amount of hyperbole that comes from elements of the Scala community on actors I think is a cause of a fair amount of vitriol, mostly because actors are not a silver bullet and come with their own host of problems. Akka is trying to solve some of those problems of course :)
And of course the lack of tools. It's hard for me to talk about this because I loathe IDEs. So far I have been writing my medium sized project entirely in vim + NERDTree and it's been great. I imagine with enterprise scale projects I would start to miss Eclipse though.
I know several (good) java programmers which thought they should without learning be able to understand/write idiomatic scala code. But idiomatic scala has also a lot of concepts (functional programming etc.) which they just don't knew.
I've given up PHP for Scala recently, and it doesn't seem too difficult yet. Do yourself a favor, pick up a copy of "Programming In Scala" by the languages author, and read it starting from page one, even if you think you're an expert programming.
I can't learn a new language quickly, so to learn I'm blogging about my experiences at http://leftnode.com and trying to write as many small programs as possible, moving into larger ones when I'm ready.
I'm trying to ignore many of the larger projects and in-depth Scala projects for the time being so I don't overwhelm myself and give up on learning the language.
I used scala for a few projects, and overall I like it much more than java. Let's just get that out of the way upfront :)
I loved scala when I was writing and reading my own code, but it started to feel like perl when I had to use and dig through other peoples code. This is a fairly superficial feeling, and I could be off mark, so take it with a grain of salt. I definitely plan to use scala again when I need the performance over jruby/clojure, in place of java of course.
I have the same problem with learning Ruby. The official tutorial basically runs you through "regular" style imperative programming. But when you see real-world Ruby in the wild, it's always so cryptic, and uses popular language features that don't really get touched on in the tutorials.
If you're talking about the Picaxe book, Ruby is all about meta-programming, so that's only a book to get you started. I also think it's a highly overrated book and personally I haven't had the patience to read it.
Ruby code gets really clear when you understand "self", eigenclasses and closures.
The pickaxe always struck me as Ruby from a Java programmer's perspective. At one point it was one of very few options in English but nowadays the choices are better. Ruby Best Practices and The Complete Rubyist are key reading.
I remember reading early Rails code and - bang - everything is obscure notation for class member of private class using the '@' symbol or something (along with eval expression that would clearly slow down everything and ... did).
A bit off topic rant on the Eckel's article linked in the post.
1. I wish people stopped saying "static language that feels like dynamic". This is just a marketing slogan. Type inference is not a substitute to dynamic typing.
2. I know that coming up with a good, plausible code examples is difficult but it's not an excuse to give bad examples. House has-a Bedroom; House not is-a Bedroom.
3. > Scala has the best of both worlds: true multiprocessor parallelism and a powerful functional programming model
This sounds as if usually multiprocessor parallelism and functional programming are mutually exclusive and Scala finally managed to have the best of both worlds.
4. > v.foreach(println)
... eh, isn't this just passing a named function as a parameter?
Coincidentally, today is the first day I'm seriously looking into Scala, and I think his points serve well to temper one's approach to language.
I think Scala is an admirable and ambitious effort to allow oo + func programming on the JVM. I also got the impression that the type system is "good enough" for most DRY efforts. But then, my background in this area is virtually non-existent.
Depending on what sources you learn from, you don't need to learn all the intimidating language features in the beginning itself. I am currently working through [1] - well written, but slightly outdated. [2] is where I got oriented initially.
It's also great that they do well to come within striking distance of Java in performance (this is not my impression of Clojure). Another super cool approach seems to be that of Mirah (no special runtime, Ruby-like syntax).
I've found Scala to be more intimidating to approach than the average non-functional language because the people who tend to use and write about it are of a relatively high level of expertise.
I'm rather sold on it, though. I've been warily learning it in dribs and drabs for about a year, and one of these days will actually write something that accomplishes a task.
And how many people running Scala are actually using those other JVMs? How many of them even compare to the Sun/Oracle JVM? I mean, honestly? And given Oracle's new penchant for suing people and their spat with Google/Apache, do you really want to keep your eggs in that basket?
People keep trying to sell new languages to Java developers using the JVM. The problem isn't the language, though, it's the JVM itself and the licensing problems, too.
That brings us to point (1) of his article. He asks us to make a large investment in learning a language that might pay off in the future... might.
My understanding of Scala is quite imperfect but the more I've learned the more it seems that it's got pretty facades built over weak wood. Rather than being a 'scalable language' it comes across like a fake town that was built as a set for a Western. Look at any beautiful concise code sample that they try to seduce you with and you find that any small change requires tripling the code size. Look at the chapter in the book on DSLs and the take-away is "don't try to build internal DSLs".
Be it looking at the profiler running on on a Scala program that uses actors or finding that I never quite seem to get away with not having to declare types explicitly, I have a facepalm event every hour or so working with Scala.
In my case, (2) has nothing to do with it. I'm quite familiar with functional programming, both in languages that support it well and languages that don't. These days even my PHP looks like LISP.
(3) is certainly true, and I think it has something to do with the cultural difference that @speckledjim points out.
Anyone who's got to work with Scala will definitely confront (4); if you're working in Java or PHP or some other commercially viable language you can probably solve a high fraction of problems by using Google and Stack Overflow.
If you're programming in Scala you'll have a lot more success understanding the fundamentals of the language. If, for instance, you need to access Scala objects from Java (particularly the super-prevalent ones like Option and List) you'll find that cookbook-style documentation is 100% AWOL. Go look at the scaladocs for Option and List, however, and you'll be calling methods on them in no time from Java.
If you insist on working with Scala, get a book and read it all the way through from the beginning, skipping forward when you don't understand something.
Look at the chapter in the book on DSLs
and the take-away is "don't try to build
internal DSLs".
Which book do you mean? Also, do you mind elaborating on why one should avoid building DSLs with Scala? In my own experience [1] I've found it extremely nice for internal DSLs.
Presumably he means Ordersky's Programming Scala. While it is possibly one of the better Scala books available it is downright bad, having committed the doorstop producing sin of confusing a language tutorial with a reference with a thesis defense. The second edition of the text is all over the place, providing little in the way of even trivial program examples and maintaining shockingly conservative advice from the first edition, written for the language in its state a few versions back.
The assessment that Scala is a pretty structure built of weak wood is not too far off, at this point. Compared to other strongly functional languages--Haskell and ML, say--the type system is shoddy and limited. In part this is a frustration of maintaining objects on Java's terms, but also defects in the JVM: type erasure is a hair-shirt that neither of languages I mentioned previously have to wear. You can somewhat avoid the loss of types with manifest hacks, but it's shoddy business. Often you can't; note that Akka has a distinctly dynamic feel, being that certain messaging functions--!! and !!!--must return an Option[Any] even when the original message is well-typed. The system loses the type information at runtime!
Compilation speed is also an agrivation. It's a slower process than Haskell--not zippy to begin with--and comes with less result, to boot. All that said, I tentatively like Scala, especially if a project is required to run on the JVM. I find it to be an especially pragmatic language, if unbeautiful and not something I intend to use for long-term, exploration coding. A fine choice for a language to be used in anger, let's say, if the memory usage of the JVM is of no concern.
Scala doesn't have Hindley-Milner global type inference (of which OCaml has an extended version of) and instead uses a form of local type inference. Hindley-Milner doesn't work well (i.e. undecidable) in the face of overloading and inheritance.
Oh, sure. Sometimes types disappear at compile-time and aren't needed during program execution: the theorem is already proven so why should the runtime system carry around the baggage? Unless we're talking past one another, the Scala problem is rather worse: start passing around Seq[Seq[Int]]'s through your code and the compiler will be unable to ensure that it's always a Seq[Int] stuffed in there; the compiler comes with warning flags, but it's rather a bother and decidedly more dynamic.
You are quite correct, almost all strongly typed languages perform some type erasure for efficiency purposes. The problem, as I see it with Scala, is rooted in defect in the JVM; the system looses type information and cannot verify at compile-time that all your types will be correct.
Please correct me if I'm wrong or have misunderstood you.
I don't know Scala -- but it sounds like a compile-time type-verification problem more than a type erasure problem.
When Haskell targets x86, the x86 opcodes surely don't help Haskell verify that [[Int]] really has [Int]s in there, but it's not necessary because it is proven at compile-time. So I am a bit confused why Scala needs the JVM's help.
Consider that Haskell does its compilation step once; the types and their parameters are discarded and machine code is generated up front. (More correctly, LLVM IR is generated and combined with the Run Time System into a binary.) In Scala, and Java before it, compilation happens during program execution: you cannot discard types because the compilation step is never over. Ordersky's previous work on Pizza ensured that, however, that type parameters _were_ lost; rather than modify the JVM to support generics it proved to be more expedient with regard to backward compatibility just to strip them out. Pre-generics binary code could co-exist with post-generics because they compiled down to the same bytecode. Hence the complaint that in Java Array[Int] and Array[String] generates two special purpose, 'parameterized' Array structures in memory. Mostly the Java compiler can be clever and produce relatively only what is needed during execution, but the PermGem exception happens because, well, it's a hack.
Now, consider the difficulty of Scala wherein it's possible to represent a compound type. Erasure ensures that only the first parameter in the chain is generated in the type-erasure step, destroying the meaning of the union. There are kludgy ways around this--wrapping, bundling up manifests--but in the end the JVM does not allow the transmission of necessary information efficiently. Manifests serve the purpose of maintaining parameter information at runtime, but do so at the expense of code cache space and stress system resources. PermGem exceptions are much more common, in my experience, when doing Scala work as compared to Java.
The shorter answer to your question is the JIT nature of Java combined with a byte-code designed not to maintain the information needed to generate all possibilities of machine code on demand. LLVM IR maintains such information for Haskell--when targeting machine code directly I believe this is achieved by static polymorphic compilation, but I could be wrong; Stack Overflow time?--and the CLR does the same for C# and friends. It's a JVM problem entirely. The JVM promises to perform any and all compilation but is unable to accept all the information needed to do so effectively.
The Wampler & Payne book "Programming Scala" works an example which is absolutely painful.
They're able to make a language that sorta-kinda looks like plain English, except that it's based on structurally unstable idioms that would require the user to be familiar with all of the corner cases of Scala syntax if they actually want to use it.
That said, I own a whole raft of Scala books, including the original by Odersky, the yellow-black Apress one and so forth; and of all of them, I find Wampler & Payne the most approachable and useful.
That's fair. Indeed, I've found that general purpose programming languages are not the ideal platforms for DSL development (my previous comment about Scala's fitness in this regard should be taken as a relative statement). That is, there are many idiosyncrasies of the host language that leak into the DSL, error handling/reporting is hard and tends to obscure the code, and the eventual DSL tends to have a very hosty flavor.
What we need are special-purpose languages designed for creating DSLs.
If you care about shipping products, it is worth it to care about the tools you use to ship the products with.
Some languages are fashionable because they are neat. Some languages are fashionable because they have allowed people to ship products better and faster. Some languages are fashionable because of both.
There are a handful of commercial success stories with Scala, like the messaging engine behind Twitter, but not a lot.
I can definitely see how an individual or small team could build something fiendishly clever in Scala that's maybe 2,000 lines of code that does the work of 20,000 lines of code in some other language.
On the other hand, I'm not sure that systems 10x that size developed by bigger teams would succeed in Scala, and I fear for what happens when that 2,000 line Scala system falls into the hands of maintenance programmers.
There are a handful of commercial success
stories with Scala
Correction: There are a handful of commercial success stories with Scala made public. There are companies trying to solve hard problems with Scala that are not necessarily interested in language advocacy.
small team could build something fiendishly clever in
Scala that's maybe 2,000 lines of code that does the
work of 20,000 lines of code
I actually provoke you to pick a language, any language other than assembler, and write a piece of software with both languages, of reasonable complexity (no micro-benchmarks shit), as concise as you can.
If the source-code in Scala is at least 3 times smaller, I'll buy you a drink.
I work as a consultant in Bangalore; most of my daytime job involves reviewing projects (for code quality). I see about 8-10 projects a month (Java/.Net).
There are projects which are just bad, let's ignore those. Those which can be classified as maintainable, are well structured and object-oriented, they abstract implementations behind interfaces etc.
But, they are verbose. I could probably accomplish the same thing in about 3x less code using FP/declarative constructs.
Reminds me of Yegge's Kingdom of Nouns; it is a funny read if you haven't read it yet.
He made his statement in the general sense, and I responded in the general sense. I don't know scala and can't speak to it. But I've heard that exact same sentiment applied to ruby (rails, specifically). But ruby has enabled huge increases in productivity for me over php. So I can safely say that the sentiment that if one is doing something fashionable one must not care about shipping, is full of shit.
If you're shipping products and making things of value using great tools (however fashionable they are) it means you spend more time shipping and adding value and less time dealing with the limitations of your tools.
I think this is just a case of different viewpoints. The author clearly states himself in the last paragraph that learning Scala in under 3 weeks should not be expected. Personally, I consider any language that I can't learn to a reasonable level in 2 days difficult.
Any language which uses concepts which you haven't used before (Like Functional Programming or in the other direction OOP etc.) will need more than 2 days. You will need the time to learn the new concepts and not the language. So the language per se isn't difficult but the new concepts...
I've been an OO programmer for a long time and I really, really like the way functional programming works. It takes some time to re-think your previous assumptions, but even when in pure Java, a more functional approach provides a much better code.
And, maybe it's because I've used another languages that I find Scala pretty straight forward.
The perfect Java replacement would have - local type inference, less verbosity (e.g. public by default), full closures, anonymous blocks, no generics, special syntax for arrays and hashes, operator overloading and the ability of a variable to behave as if dynamic (e.g. leveraging the future InvokeDynamic). I would also completely purge checked exceptions and also get rid of the general syntax for anonymous classes - basically get rid of anything not useful.
People actually liked earlier versions of Java. It was a simple language, while still a lot more productive than C++. They fucked up its evolution and IMHO it's pretty sad that people like Scala so much; it just shows how low are the standards.