Hacker News new | past | comments | ask | show | jobs | submit login
Why Java Now Rocks More Than Ever: Part 1 – The Java Compiler (zeroturnaround.com)
104 points by mustapha on Oct 7, 2013 | hide | past | favorite | 147 comments



Beefs with this article:

1. Runtime-linking _is_ dynamic linking, and it's a PITA that Java doesn't have an option for static linking, especially given the inherent fragility of the CLASSPATH.

2. clang and gcc have compatible command-line option syntax.

3. The options example he lists for gcc is a pure strawman. Maybe they are necessary to compile that particular source file, but it is not necessary to use all these options in the average case.

4. The article title says "now more than ever", but there's really nothing about recent developments here. This article could have been written ten years ago.

This really just seems like crappy linkbait.


> 1. Runtime-linking _is_ dynamic linking, and it's a PITA that Java doesn't have an option for static linking, especially given the inherent fragility of the CLASSPATH.

It is possible to roll a 'fat' JAR with all your dependencies baked-in, which is as close to static linking as it gets in Java-land. I prefer this for stand-alone applications as it makes deployment a cinch at the expense of the size of the build artifact.


Agreed, this is how I do my Java standalones. Eclipse makes this easy with Export | Runnable Jar providing several options for how to package the build.


The Maven assembly plugin can also do this with the 'jar-with-dependencies' descriptor.


I personally use the maven-shade-plugin for this because it has built-in support for handling special resource files like licenses, service definitions, and manifest entries.


The maven shade plugin can be dangerous if you hit the zip file limit of 65535 entries. Watch your filters.


I wonder how such a setup would play out in regards to Open Source usage.

Say you create a big jar with all dependencies in there in several layers of "lib" folders.

Licenses like LGPL say you have to keep the LGPL archive accessible to the user and grant permission for them to alter/update them.

Would a nested hierarchy of lib folders inside your jar be viewed as hindrance? Certainly you didn't "hide" the LGPL'd components in order for the user to not alter them but I think it could be viewed as "security through obscurity". If I don't immediately see a component, how do I know its there? I guess this could be solved by a readme that lists in detail what open source components are used and where in the hierarchy they can be found.


Yeah, I've used jarjar before for this.


Good point(s), especially #4. The article compares an 80s language (C++) to a 90s language (Java), not to more recent compiler toolchains. Admittedly, there aren't many options here, and e.g. Scala (which I hope will be covered in future articles) relies on the java toolchain.

Edit: C++ and Java also have different cultures. The simplest compilation with g++ is "g++ foo.cpp -o foo", which isn't much more complex than "javac Foo.java". The fine-grained options clang/g++ give you are part of the “you pay for what you use”-mentality of C++.


Except there are 70's languages (Modula-2), 80's (Ada) and 90's (Turbo Pascal/Delphi), that offered more powerful compiler toolchains.

However, given C++'s requirement to be kept compatible with UNIX toolchain model, we suffer from a 70's model in C++.


Regarding #1, Java 8 allows for static JNI linking. http://openjdk.java.net/jeps/178


Cool. Did not know that.


Moreover, their own banner ad at the bottom is ironic. "Java is cured, suffering from redeploy madness. Get your cure".

http://zeroturnaround.com/wp-content/uploads/2013/09/660x122...


Didn't you hear that all that changed since Twitter switched, and now it rocks more than ever?


Most importantly, his gcc example is taken from OSX... ugh.


As the guy says he is writing music software, Mac OSX would be a pretty important platform to cover.

That said, I'm a recent convert from Linux to OSX, and I like to tinker with Garbage Band from time to time :-)


> All this is only worsened by the ‘black box’ nature of the optimization level switches.

JVM switches like -XX:CMSInitiatingOccupancyFraction=70 -XX:SurvivorRatio=2 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:NewSize=2048m -XX:MaxNewSize=2048m (taken from real recommended settings for an open-source project) are, of course, not opaque-to-the-average-user at all :)


http://www.oracle.com/technetwork/java/javase/tech/vmoptions...

The page existed for over ten years (Under different domains) and countless tutorial and presentations about hotspot covered them.


Sure. There is also extensive documentation on what GCC flags do. Neither JVM flags nor GCC flags refer to deep dark secrets.



You are right, but newer Java versions have what is called "GC ergonomics": you simply define either a throughput or a latency goal, and the JVM tries to dynamically change the settings until to achieve your goals.


Some applications can be pathological, in which case you are better off setting lower-level flags. For example, Lucene both churns through tons of short-lived strings and tries to maintain caches of large arrays. The memory/gc optimizer handles this very poorly.

Between modern Java tending to move caches to unmanaged memory-mapped regions as libraries mature, and the potential of G1 as a concurrent compacting collector, we're on the cusp of not having to worry about any of this anymore.


By the way, I'm not complaining about Java here. I _like_ Java (or at least I like the JVM; the language is something one puts up with, or sometimes not, for the JVM). I just don't think it's terribly fair to say that c compilers require all these arcane options for performance, without noting that JVMs have their own just-as-arcane (or maybe moreso; garbage collection is harder to wrap your head around than compiler optimisation, and can hurt you more) options which are required for performance.


If you're using the new G1 collector which ships in JDK 7, the only configuration parameters you really need to care about are the minimum and maximum heap sizes (-Xms and -Xmx) and perhaps the latency target (-XX:MaxGCPauseMillis).

So it's not all bad.


Well, this is the theory, certainly :) I haven't found it to necessarily be true in all cases.


One of my favorite tricks not often used: -XX:MaxTenuringThreshold=0

Higher throughput when you have lots of short lived objects.


Java is rapidly becoming more viable as an alternative to all of these "trendy" languages these days, e.g. Ruby, Python, Go.

What I mean by that is simply that a lot of developers are prejudicious against Java due to historically it being slow and having tedious development feedback cycles.

We use Java extensively (and Java EE 6) in an agile IT business and it is truly an asset. I encourage others to look in the direction of Java.


One problem of many is that Java is quite verbose, and while IDEs like Eclipse help with this, there's a significant contingent of open source developers who both refuse to use typical IDEs and who also like to manually manipulate their code rather than let an IDE tweak it about. Languages like Ruby and Python make that easily manageable in a way Java doesn't.


Java is certainly unnecessarily verbose, but if you compare it to other statically typed languages (like C++, C# or Go) and subtract the verbosity that is purely cultural (overdesign) it's not quite as verbose as it sometimes seems.

Comparing to dynamically typed languages (and even to statically typed languages using a lot of type inference) is a little tricky, because in some cases "verbose" means you have information available locally that you would otherwise have to look up elsewhere.


> verbosity that is purely cultural (overdesign) it's not quite as verbose

This is absolutely true, especially with Java 8.


Going by LOC: I find I write less Scala than Ruby to accomplish a thing. To be fair I don't really include import statements in that comparison since I rarely actually write an import manually (IntelliJ alt+enter completion).

Learning where things are in the stdlib for Java is different, but not harder than Ruby IMO. Where is MD5 in Ruby? Or DateTime?

I can and do code Scala in ST2 on occasion. Mostly for gists. IntelliJ just makes working on bigger codebases nicer.

Anyways, just an opportunity to say: You don't necessarily have to trade in performance and verbosity. You can get a relatively succinct language, with much better performance, and still enjoy the ecosystem.


There are languages on the JVM as well with far less boilerplate, that still give you static typing, performance that is compatible with Java, and the whole ecosystem.

For instance, Scala and Kotlin.


Plus they tend to avoid all the excessive XML tooling and configuration that goes along with J2EE. Compared to nearly any other templating system, JSP is one of the most tedious I've encountered and try to avoid. I had the displeasure of using it a while ago with Struts for a project at my University and hope it will be the last time I ever have to use it.

I assume it stems from Coldfusion and it being popular around the time of the rise of Java, but to continue that tradition nearly 20 years later of XML templating/configuring everywhere just deters professional developers of nearly any other language.

There are some non J2EE Java frameworks that try to remedy the faults of J2EE, but it's kind of given Java on the web a bad rap.


J2EE was last released 10 years ago. Since then its been JEE and with the latest you should not have to use XML for configuration only when you want some really odd config instead of going by convention.

JSF2/Facelets replaced JSP in the most recent JEE standards and is much nicer to work with.

I mean JEE 1.6 was released 4 years ago (around the time of Rails 2.0). For a standard that is not bad.

We actually use a lot of apache wicket which is a very nice framework for website/applications.


Interesting. Thanks for the info and I'm glad to see things have changed for the better. I'll have to search around when I have some free time for more details.


Scala's compilation was really slow the last time I tried. It's also a really complex language and I found some parts ugly.


I find most of it ugly. But I'm looking forward to Kotlin. I believe Kotlin is what most of us had hoped Scala would be when it first came out, before it turned into the unholy Java-Haskell-Lisp-C++-Javascript hybrid that it is today.


I quite like Kotlin at first sight but I currently use Eclipse... (looks much better on Linux than IDEA) I'm also looking forward to Ceylon.


For Ceylon I believe Java integration is a secondary concern, while for Kotlin it's one of the most important ones.


In their FAQ, they say "Java interoperability is a major priority for the project."


Honest question: Are their refactoring IDEs for Ruby, Python, or other dynamically typed languages?

Agree 100% about Java's verboseness. I really want type inference, lightweight objects, properties (vs JavaBean accessor convention), switch for 'instanceof', etc.

However. Java's verbosity is nothing compared to the verbosity of the common APIs and frameworks. All that DI, IoC, configuration via markup, etc. are terrible efforts to make Java more like a dynamic programming language. Even the built in APIs have design pattern-itis, with types, hooks, hierarchies aplenty.


> I really want type inference, lightweight objects, properties (vs JavaBean accessor convention), switch for 'instanceof', etc.

I believe you're asking for Scala. For example, switching on types:

  trait Foo
  class Bar extends Foo
  class Baz extends Foo

  val thing = // could be either bar or baz, don't know  

  thing match {
    case f: Foo => println("Got foo")
    case b: Bar => println("Got bar")
  }


:)

Our study group has done two Scala tracks (and currently studying Akka and reactive programming).

Ruby and Scala make my head hurt. I don't have a mental model for what's happening under the hood. Unlike LISP, Forth, Java, etc.

I really do want a refined, simplified Java. My wishlist of features are gleened from Boo (minus the duck typing), Nice, and Kava (lightweight objects).

http://boo.codehaus.org

http://nice.sourceforge.net

http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.19.3...

Honorable mention for Frink (preserves units).

http://en.wikipedia.org/wiki/Frink


You're not alone. Scala has the features you're looking for, but it's also a mashup of Haskell and Lisp and C++ and a few other mismatched languages. As I said in another comment, Scala is for people who find Haskell too simple, and want to add mutability, inheritance and macros on top of it.

I think that what you're really looking for is Kotlin: http://kotlin.jetbrains.org/


Can you give an example of something in Ruby that makes your head hurt because you don't know what's going on under the hood?


> Honest question: Are their refactoring IDEs for Ruby, Python, or other dynamically typed languages?

Yep, Intellij IDEA does it pretty well, or one can get their language of choice individually as WebStorm (JavaScript/NodeJS), PHPStorm (Webstorm + PHP), PyCharm (Python + Webstorm) or RubyMine (Ruby + Webstorm).

The refactoring and type inferring abilities for dynamic languages in each are pretty amazing. Types can also be inferred by docblocks and return types as well in each IDE for code analysis to avoid silly mistakes. That, along with refactoring has saved me tons of time and a reason to use a full IDE over a more lightweight editor. They also have an open source version of the Python IDE if you want to try it out.


The 20-50x performance tradeoff is a hard pill to swallow though. I'd love to see a better performing dynamic language that isn't as minimal as Lua.


It is called Common Lisp


Or Clojure.


Common Lisp has the advantage of having native code compilers available.

On the other hand, it suffers from not having a big ecosystem.


Is that really the case in real world loads? I have always thought that the moment you avoid blocking io and code almost any language is fast enough. And usually the problems come from bad design.


Well, it very much depends what you're doing. Obviously, if you are doing something CPU-bound, code speed is pretty important. Not sure what blocking IO has to do with it one way or the other. Are you thinking specifically of webapps, maybe?


I've come to think of it as a plus that the entire semantics of a language can fit in working memory. What features do you find to be missing from languages like Lua and Scheme?


This is one of the reasons I use Go in favour of pretty much anything running on the JVM stack.

I don't have to change my workflow at all between working in Python, C, Go and JS. I can use vim for all of the above and none of them force me to have years of experience with an IDE in order to be productive.


Sure. Go is pretty much a JVM-less Java. To me, it seems the exact wrong things to take from Java. Go takes the language (Go is a simplified Java, with some modern improvements) - which is only OK, but drops the JVM, which is awesome.

It does have one advantage over the JVM, which is a much shorter startup time. But Java has better performance and far better monitoring tools (as well as dynamic linking and hot code swapping).


I think calling Go a simplified Java is pretty far off the mark. Aside from both aiming at the niche of being sort of "medium-level" languages, for lack of a better term, Go's approach seems very different from Java's.

Objects vs structs and functions, exceptions vs multiple return values, required static vs required dynamic linking, implicit vs explicit subtyping/interfaces, etc.

Go is C with added convenience.


Structs + interfaces in Go are a re-interpretation of Java interfaces (albeit a major one). It's a different path, but the same philosophy (dynamic dispatch over receiver type + mutable state).

Exceptions vs. multiple return values are two different local decisions made by Go's designers: multiple return values and lack of exceptions. Multiple return values are handy (might find their way to Java one day), but I would call that a feature, not a different approach. As for exceptions, it is my understanding that Go's designers haven't made a final ruling on the subject.

Static vs. dynamic linking are properties of the runtime (native vs. VM) rather than the language. In principle, both Go and Java could support either without any language changes.

Go is most certainly not like C, because C's philosophy is letting the programmer work at the same level as the CPU. Go, if anything, is further removed from the hardware than Java (no explicit control over threads or scheduling, no access to memory fences).


I was mostly referring to the style of programming the languages encourage. Things like multiple return values instead of exceptions are extremely significant in what they imply about how you're intended to code in the languages.

Go tends to be written like a low-level language with very good high-level libraries. You don't have huge class hierarchies; instead you have functions. You don't have a million custom exception types; you just return error codes. Go is obviously closer to Java with respect to some of the things you can do with those concepts (things like switch statements being very general are features of much higher level languages than C, etc.), but as a programmer, you're still writing a switch statement, not a series of polymorphic methods dispatched at runtime. That's what I mean -- Go is very, very unlike Java if you're writing idiomatic code in each.


Not so! Go explicitly exposes indirection, while every Java object is a pointer. The result is that control of what is in L1 with Java is impossible, while memory locality can be forced in Go.


Struct arrays are sorely missing from Java (hopefully they'll be included in Java 9), but other than that, an object is allocated contiguously in memory. In fact two objects allocated by the same thread one after another will be allocated contiguously, so "inner" objects allocated during objects construction will be adjacent to the original object.

Go's designers have said that they wanted to experiment with a more direct approach to memory in exchange for a less advanced GC.

So, you are right that in terms of memory placement issues, Go is more low-level than Java, but it's higher level when it concerns scheduling. All in all, it places them pretty much at the same level. It certainly doesn't make Go closer to C.


I'm learning Go right now by writing a small part of my current project in it. I like it quite a lot (mostly for its concurrency features) but it is actually a surprisingly verbose language compared to Java.

First of all you have this on about every second line:

  if err != nil {
    return err
  }
Method signatures are convoluted because you have to repeat the receiver type for every single method and add (actualReturnType, error) at the end.

Go:

  func (MyType* mt) myMethod(s string, i int) (string, error)
Java:

  String myMethod(String s, int i)
For functions you want to use in expressions you need a second one that calls the first one and panics instead of returning err.

You can't specify default values for structs, so you often need an extra function that constructs a default instance of the struct and initializes its fields.

And the lack of generics means you have to write a lot of things several times for different types.

Lambdas are very verbose as well. You get no type inference even in contexts where it would be simple to do:

Go:

  filter(func(s string, n int) { return len(s) < n })
Java 8 (Scala is similar):

  filter((s, n) -> s.length < n)
Function names often have to be longer because there is no function overloading.

Go's simplicity is a double edged sword. Lack of verbosity is definitely not its strength.

Obviously there are many counter examples where Java is more verbose than Go. But they are very well known by now so I'm not going to repeat them here.


You can do that with Scala as well. (or groovy or clojure...)


I like verbose. Some of the bloated patterns populat in enterprise Java are overly verbose, but the language itself is pretty nice for me.


I've always been confused by this. I use Jetbrains (IDEA, Rubymine and PyCharm) products almost exclusively and I have no idea why a developer would "refuse" to use an IDE.

I admit that if I just need to review a single file or knock an R script together I will launch Sublime. This is almost exclusively as a result of launch time ... nothing more. Good IDEs tend to get out of your way - whilst offering you advanced visualisation, debugging and reporting for when you, ... you know ... have to work with other people.


As a Java and Clojure developer, I wholeheartedly agree, but your premise suffers from HN/GitHub bias. The amount of software written in Java (and you can add other JVM languages too), both in terms of developers as well as total features worldwide handily dwarfs Ruby and Python combined, possibly ten times over.

Just to get a sense for this bias, consider that IBM alone employs more than the number of employees in Google, Facebook and Twitter combined, multiplied by 9. If you add banks' huge IT departments, defense companies and more, you'll find that the entire Web software ecosystem is on the order of a few percents of the entire software industry.


What I like most about Java is that you can switch more easily to certain fashionable languages (Scala and Clojure) which have good interopability with Java because they use the JVM.

Sources for this claim: http://www.slideshare.net/tackers/how-we-mostly-moved-from-j... http://java.dzone.com/articles/moving-java-scala-one-year

Counterpoints: Couldn't find any data on how well Clojure works with Java apps. Scala's decent interoperability appears to stem from a Maven plugin rather than directly from its ability to use the JVM.


Clojure's Java interoperability is better than Scala's. For example, Java collections are automatically treated as Clojure collections with no wrapping required, any Iterable is a seq etc.


+1

Convention over configuration, scaffolding similar to RoR (or better with Forge) and advanced meta-programming via annotations have reduced the effort to produce CRUD applications to a level similar to the trendy languages and frameworks.

While J2EE was painful (10 interfaces and classes for some Entitys), JavaEE is fun to work with and (for the most part) intuitive as it's focused on POJOs and includes DI (CDI). Now I focus on my business logic, and let the rest of the pieces fall into place naturally!


So true - enjoying working with Java EE on a daily basis. I am not always entirely satisfied with Glassfish though (my application server of choice), so I'm willing to consider others. What are you using, perhaps JBoss?


Nobody has ever used Ruby because he thought it might be faster than Java. Java primarily competes against C++, not against “scripting” languages like Ruby and Python which have significantly shorter edit-(compile)-run cycles. Each of these languages also have unique features that are difficult or cumbersome to model in Java (functional programming, metaprogramming, modern object systems).

I do not doubt that there can be cases where a transition like Python → Java can make sense, but it would be silly to assume this would generally be a good idea.


Short edit-run cycles: check (Scala REPL, JRebel, Play Framework) Functional programming: check (Scala, Clojure, Java 8) Metaprogramming: check (Scala macros, Clojure) Modern object systems: don't know what you really mean by this, but Scala's object/type system is pretty cutting-edge.

Now, what about static type system and IDEs finding type-errors when I write code? This is making development fast. Having to run unit-tests or the app itself whenever I change somehing is damn slow.

Also, what you gain by short edit-run cycles in Python/Ruby, you waste when you have to do any major refactoring (again - lack of static type checking). I programmed a serious app for a bank in Python, and, long term, just because of this, development wasn't any faster than with even pure Java.


The Java language itself is pretty verbose. There's a reason why "trendy" developers on the JVM have long since moved on to Scala.


This. Java's syntax and core API is pretty much stable compared to the hot languages championed by so many HN readers. Updating applications written with the "hipster languages" is like pulling teeth. It has a serious impact on an application's maintainability when the language's core API is constantly changing.


Have you ever programmed anything substantial using java outside the enterprise/agile IT environment? Any type of project on your own time? Have you every built anything in Ruby, Python, or Go? I'm asking to try to discern what you mean by "more viable".


You don't provide any reason why I should switch from a language I like to Java EE 6. "it truly is an asset" and "I encourage others" is not a reason.

It's not prejudice when it is true.


Python and Ruby aren't trendy anymore.


One of the things I see with Java today, how difficult things have gotten with the language. Its next impossible to deal with any large Java project without an IDE. The verbosity of the code is mind boggling. Often method calls are 4 - 6 layers deep, which in itself makes is very difficult to remember or even implement even if you read the documentation well.

The resulting code is massive walls of text. 90% of that is machine generated through eclipse. This is an indication that the language idioms are unable to support the current complexities in application programming trends. And you have to interplay with them heavily to squeeze out usable programming logic.

That doesn't end there. Perl is older than Java, yet despite that I see Perl can support a lot of idioms far far better than Java can with its bulky frameworks.

Its just that the language is beginning to show its age.

The only reason to use Java these days is basically availability of super low cost devs, Legacy code, tooling etc. Basically for reasons as with any tool that has an advantage with age.


> Its next impossible to deal with any large Java project without an IDE

True, but I don't see it as a problem (for me).

> The verbosity of the code is mind boggling.

I don't find Java that verbose (especially with lambda functions in Java 8).

> method calls are 4 - 6 layers deep

I don't understand, do you mean nested method calls?

> 90% of that is machine generated through eclipse.

Definitely not 90% and lot of the generated code would have to be written manually in languages like Python.

> The only reason to use Java these days is ...

Libraries, tools, speed, multiplatformity. Also, Java is a pretty good language by itself. It lacks in many ways, but for a LOT of projects, it's a great choice. What language would you suggest as a Java alternative?

> super low cost devs

Java devs are among the most expensive.


> I don't find Java that verbose (especially with lambda functions in Java 8).

Honestly: use something better for a while and come back and say that. Java is verbose. There is a ton of ceremony around anything in it, from ill-considered defaults that require lots of specification (see Scala's remarkable ability to strip bullshit out of its equivalent to Java code) to the cultural design-pattern mess.

It's a lowest-common-denominator programming language, and it shows because it takes such pains to spell everything out every time. JDK8 lambdas sort-of help, but the language is still fat.

> I don't understand, do you mean nested method calls?

I think that's pretty straightforward and that these two go together.. You basically have to use an IDE (and while I am comfortable in an IDE this is a negative in the general case due to the complexity it implies) because you need go-to-definition all the time due to what is, frankly, class and method bloat. This method hands off to this manager class method which hands off to this class that exists just as a temporary stateful container and all of them add more boilerplate and force you to maintain more mental state and blurgh. I was guilty of it as a younger programmer, but I've aggressively tried to move away from that; some people don't seem to ever grow out of it.

> What language would you suggest as a Java alternative?

Scala. I'm a former Java web dev, current Android developer, and if I could shoot all my Java code between the eyes and replace it tomorrow with Scala I'd be a happy man. It's a language that aggressively attacks the idea of design patterns by making the language more expressive (whereas Java just codifies them).

My new projects are exclusively Scala, and I'm turning out better, more readable code in shorter time. The JVM is fine, but Java-the-language and Java-the-culture are toxic as hell. And while it's no doubt harder to hire Scala programmers, the floor on quality is going to be a lot higher than Java programmers when I need to hire them.


> the cultural design-pattern mess.

While it may have become cultural, the design-pattern mess is directly related to the limitations of Java the language when applied in its typical domains of application. The reason many languages whose features evolved in light of the Java design pattern mess don't share that mess isn't purely cultural, it is because the features of those languages were designed specifically (often drawing from older languages that didn't have the same problems as Java but which weren't popular in Java's role for other reasons) to overcome the limitations that require those patterns in Java; this is perhaps nowhere as obviously the case as it is with Scala.


> While it may have become cultural, the design-pattern mess is directly related to the limitations of Java the language when applied in its typical domains of application.

Totally agreed, I definitely elided some stuff there. They definitely exist to get around limitations in Java's expressiveness, and I cringe every time I end up writing them (day job is Android, and Scala there is iffy at best).


> Honestly: use something better for a while and come back and say that.

I've written code in about 20 different languages.

What language features / lack of features do you think make Java verbose?

I found Scala complex and ugly (and I'm not alone), much slower to compile than Java and Java has better tooling.


- No pattern matching. This alone basically makes the rest of this list just piling on; once you have 'gotten' pattern matching, Java (and, to be fair, most other popular languages) becomes intolerable.

- Lack of even halfassedly reified generics means you're throwing Class objects around everywhere for no good reason. (Scala adds manifests as implicit parameters and it's not as good as .NET but it's a hell of a lot better than Java.)

- Actually, let's just go with "the type system in general". For being built upon the same shitty tools as Java, they do a lot to provide an environment where thinking about types isn't prohibited.

- Inner classes being used for nontrivial things (see also: all of Android, saved only by AndroidAnnotations; all of Swing, saved only by never having to use it).

- No comprehensions. Nuff said.

- Null by default. Option types are both safer and easier to work with functionally than imperative null boilerplate.

- Nonfunctional control constructs. For example, 'if' being a functional construct makes tons of code simpler and easier to read.

- No default parameters. Dumb. Whenever they get them I'm sure it will be something less expressive than Scala's (something like "must be resolvable at compile-time") because doing otherwise will be hard.

- Braces everywheeeeere. The ability to go "def foo() = someFunc(localVar)" is awesome. Less bullshit, more code.

- Interfaces suck when traits exist. The idea that I need to write wireup code when I have getBar and getBars methods (because any sane person will implement getBar as a hat on top of getBars with a singleton list) is utterly stupid.

- Nonfunctional core APIs (where's my map/filter/fold?) that think mutability is a good thing. Guava tries to help, but it's bolting onto a fairly stupid List/Iterable core pattern.

- Reference-reseating-by-default means doing it right adds foolish 'final' keywords everywhere.

- Private visibility (or, to be specific, not-really-private, WTF?) by default means you will be splattering 'public' everywhere, too. This and the last two combine to make objects full of weird action just for funsies; if everything's immutable by default, the cases where you need 'private' to not blow up the world shrink immensely.

- Keywords and methods where operators make sense. List.add() is derpy. "T extends SomeClass" is a traveshamockery. We're programmers, computer science should not be that foreign, there are mathematical symbols to express this in type theory--so use them, as Scala does (I'd rather they used "<." instead of "<:", but I understand why they don't).

.

Scala is complex. Nobody said it's not. But it's complex because it's expressive. It's a predictable language with expressive semantics that doesn't make you do stupid shit to get things done. The tooling has reached a point where I no longer notice it and while it is slower to compile than Java, so is C++ and that doesn't bother me either because what I get is better at what it does.

I don't much care for the look of Python, but it's better and more suited to some tasks and so I get over it and use it. You may find Scala "ugly" and I'm sure you can find plenty of entrenched Java developers to agree with you, but outside of the epistemic Blub-closure of the Java world it is rapidly becoming understood that Java is better at nothing by design.


- Type erasure - true but it results in a very small increase in overall verbosity.

- Null - true but Scala's approach is perhaps more verbose than Java's. I like Groovy's approach the most ().

- Functional if - definitely disagree that it makes tons of code simpler / easier to read.

- Java 8 has traits (but I'm not sure if they're equivalent to Scala's traits).

- Nonfunctional core API's – Guava helps here.

– Reference-reseating-by-default - don't know what you mean by that.

I don't think Scala is the next Java. Personally, I wish Kotlin, Ceylon or Dart would replace Java. Scala makes the wrong expressivness / simplicity tradeoff.

> outside of the epistemic closure of the Java world it is rapidly becoming understood that Java is better at nothing by design

Not true. Yammer moved back from Scala to Java: http://blog.joda.org/2011/11/real-life-scala-feedback-from-y...


Yammer did no such thing (and it's telling that you're sourcing a two-year-old article that misrepresents the situation under discussion): http://eng.yammer.com/scala-at-yammer/

And Scala isn't the next Java. Frankly, it isn't simple enough to appeal to people who have become comfortable; it isn't unchallenging enough to supplant Java. This is not a demerit.


Right now at Yammer we're moving our basic infrastructure stack over to Java, and keeping Scala support around in the form of façades and legacy libraries.

The link you provided doesn't contradict that.

Language can be too simple or too complex. The tradeoff that gives maximum productivity is somewhere in the middle. And in my opinion, languages like Dart or Ceylon are much closer to the optimum than Scala.


I don't think you've done anything to substantiate the claim that it's "too complex"; forgive my skepticism but I've spent enough time in both the Scala and C++ communities to draw a significant line between "too complex" and "critic hasn't learned it sufficiently" (and I've been on both sides of that line).

I have spent a nontrivial amount of time with Kotlin and Ceylon and neither are particularly interesting to me after actually internalizing and understanding Scala; as an example, I am significantly hampered by their continued insistence on mutable-everywhere (which is basically the watchword for "barely adequate programmer"). They may very well be "the next Java", but that's a curse more than a compliment. You should not need Guava to write minimally competent code.

Meanwhile, as a sibling comment notes, Twitter's a lot bigger than Yammer and pretty vocal about going whole-hog on Scala (and I've talked to them a little about what they've done, it's insanely impressive, I'm jealous). Guess they're just making things hard on themselves for no reason though.


Linus Torvalds is in the C++ is too complex camp too AFAIK :)

I believe that Ceylon is the best-designed general purpose language out there. What do you mean by "mutable-everywhere"? Ceylon's variables / attributes are immutable by default.


I like working with Java too. I'm only pointing out the problems, which I see are pretty clear.

The only problem is from the perspective of using and developing a new skill, I would rather use a newer language which is better built for problems of our time than something 20 years back.

Java has had its day in the sun. Its primary purpose was to become an easy C++ for people who didn't get memory management and people who didn't want to get into tiny pedantic issues while trying to run their code on two different Unix'es. But these are by and large solved problems now. Over years a lot of legacy code has gathered around Java.

But if you want better employability especially if you want to work on new projects, new paradigms and new domains of problems you should likely chose newer set of languages. Not Java.

One hard lesson that I've learned over the years is to never have any hard religious feelings towards old aging tools. We must learn to move on, find new shores build new stuff there. The only projects you get with these older tools are legacy ones, and people are generally waiting just to phase them out.


Each newer language has one common denominator - lack of proper IDE. Even though they come with some synctactic sugar, your productivity gets nailed by lack of good IDE.

Java syntax has many problems, but they are very easy to overcome thanks to IDE and many JVM tools.


Scala tooling is quite ok now, particularly the IntelliJ IDEA plugin. Still not the level of Java, but certainly way above anything for (much older) dynamic languages.


Ok, what language would you suggest as an alternative?

I've written code in lots of different languages and I haven't found a replacement yet (C# is closest, but I mostly do Android development, on Linux).


As someone suggested earlier, Scala is probably the best option for a Java developer looking for an alternative. Runs in the JVM, is compatible with Java programs, mixes OOP and functional programming. It can be summarized as "Java meets Haskell".

What I found liberating in Scala is a simple proposition: "use OOP when it makes sense, and functional programming when it makes sense". It's wonderful when you don't have to reason about everything using the OOP lenses and you get to choose, very empowering.

Your criticism to Scala in the other comment seems to amount to "it's not Java", which is extremely weak as an argument. If you are looking for an exact duplicate of Java, then just use Java. Scala is more complex than Java, certainly, because it gives you more options and also because it has a way of rewarding those who master the language. And "ugliness" is a completely subjective matter, I find Java with all its boilerplate ugly and not Scala, for example.


> Your criticism to Scala in the other comment seems to amount to "it's not Java"

It amounts to "Scala is too complex, ugly and slow to compile."

Yammer moved from Scala to Java BTW: http://blog.joda.org/2011/11/real-life-scala-feedback-from-y...

My ideal language would be some mix of Kotlin, Ceylon, Dart and Julia.


You are just taking one data point and assuming it proves something other than Yammer had problems with Scala. Check this list of companies using Scala: http://www.scala-lang.org/old/node/1658.html

Some examples: Twitter, LinkedIn, Foursquare. All of them pretty big and in the same space of Yammer; they seem quite happy and don't plan to move away from Scala.

And here you can find a clarification from Yammer about that issue: http://eng.yammer.com/scala-at-yammer/

TL;DR: They liked Scala but it has rough edges, every programming language has rough edges (yes, including Java). They found Scala was not the best option for some particular situations and Java was a better fit. End of story.

That's fine and completely reasonable, I think nobody said Scala is the Holy Grail in programming languages. As for your preference, you seem to be looking for a "nicer than Java, but OOP all the way" (don't know about Julia, haven't used it), which is OK as a preference but many of us find it a kludge to work with. I found something like Scala (multi-paradigm, I mean) helps me a lot in reasoning about code. As I said, you use the paradigm that makes more sense.

For complexity and ugliness, you have my previous answer. About compile time, you have a sophisticated type system and type inference which come at a cost, but it's not such a big deal when you run it with fsc (which stands for fast scala compiler).


> Often method calls are 4 - 6 layers deep, which in itself makes is very difficult to remember or even implement even if you read the documentation well.

I think that's a symptom of bad design than a problem with the language. The language doesn't force you to create abstractions on top of abstractions and it is not necessary. Having method calls like that is a bad code-smell.

Java does have a verbosity problem and some of it being addressed in Java 8 with lambdas.

> The resulting code is massive walls of text. 90% of that is machine generated through eclipse. This is an indication that the language idioms are unable to support the current complexities in application programming trends. And you have to interplay with them heavily to squeeze out usable programming logic.

I have never had to autogenerate code. I use IntelliJ and it doesn't generate walls of text. It does autogenerate some stuff if you want it to, but those are usually just stubs.

> That doesn't end there. Perl is older than Java, yet despite that I see Perl can support a lot of idioms far far better than Java can with its bulky frameworks.

Well, Perl is strongly typed and has a rich (and ambiguous) grammar. I don't think it's a fair comparison with Java. Furthermore, Perl has a bunch of other issues. I love Perl, but I wouldn't really think about writing a huge application in Perl; it's usually a maintenance nightmare if you don't have a shop of disciplined Perl-coders.

> The only reason to use Java these days is basically availability of super low cost devs, Legacy code, tooling etc. Basically for reasons as with any tool that has an advantage with age.

Not really. You can build lots of full-featured webapps with Java and there are a lot of new applications that use Java.

What I think is happening more and more though, is that the JVM is turning into a platform and there are numerous languages that run on it. What Java has going for it is its rich ecosystem via core APIs and numerous third-party libraries. You have access to all of this if your language runs on the JVM. For example, Nashorn (the replacement for Rhino) has access to the standard API, as do languages like Jython and JRuby which also run on the JVM.


> The language doesn't force you to create abstractions on top of abstractions and it is not necessary.

The culture of it does. When all of the code around you is objects-as-design-pattern bad-abstraction slop, you're going to think that's the right way to do it. Which for a certain value of "right" it may be, but it still sucks. You can write "good" Java, but it's still going to be more expansive and harder to read than good C# (which aggressively trims back Java design pattern crap) or good Scala (which goes way, way further).

> that the JVM is turning into a platform

Agreed, and this will save it, but Java's not helping itself at all.


> The culture of it does. When all of the code around you is objects-as-design-pattern bad-abstraction slop, you're going to think that's the right way to do it. Which for a certain value of "right" it may be, but it still sucks. You can write "good" Java, but it's still going to be more expansive and harder to read than good C# (which aggressively trims back Java design pattern crap) or good Scala (which goes way, way further).

There is no "Culture of Java" that forces you to write over-abstracted code, and it's not really that much harder to write good code in Java. Java is a tool. Sure, it has flaws, but they're not so bad that they force you to write really bad code. With Java I've never felt forced to overarchitect anything just to get it to work. Of course, I have often felt constrained by the lack of expressiveness in the language, but a lot of that will be fixed in Java 8.


It's impossible to deal with ANY LARGE PROJECT without an IDE.

If you don't use an IDE, your project is not large yet.


This is an incredible generalization. I've very comfortably navigated codebases in the thousands of files of Python with only find and ack to guide me. I've done a lot of C# in Vim, too.

But I can't do the same in Java; at my last job we had thousands of .java files and I was stuck fumbling around with an IDE to do anything. The verbosity and repeated ceremony of the language makes it difficult to search for anything in an effective manner and the distractingly clumsy syntax (inner classes, as an example) made trying to Vim it failure-prone enough that I'd use an IDE just for the red squiggles. Those being in and of themselves concerning at times--I'd often find myself just trying to make the red squiggles shut up rather than concentrating on writing better code. I don't find myself doing that in Scala or C# or even C++.


I would say that if you need an IDE because of the size of your project, the components are too tightly coupled.

(Admittedly, I like what IDEs can do in static languages to catch errors early and improve productivity, but that's independent of project scale.)


Would you call the Linux kernel a large project?


It is not enterprise enough. If it used Java EE then it would really scale, like a stadium sound system.


> Often method calls are 4 - 6 layers deep

This is hardly the fault of the language, more of the community, which tends to fetishise certain patterns a bit.


I'd argue it's more the JVM and its ecosystem that rocks more than ever. Sure, Java is getting better, but it's the JVM and its ecosystem that seem to be impressing people and bringing fresh blood in nowadays.


Why Big Band Music Rocks More Than Ever: Part 1 - You Can Dance To It

There are still fans of Big Band music!

Java fans (or maybe I should say, employers) who want to keep exhuming this dead horse might be well served to emphasize "you can get a job" and "it's enterprise" and "JIT makes Java faster than Assembly" as they have been doing for decades, rather than tarting it up (a Java logo with an electric guitar, seriously Dad?) and comparing it to languages which are even more ancient. Java is closing in on 20 years old...


Ruby is 18, Python is 22, what's your point? I'd very much like to hear your valid criticism towards Java. From my point of view that language and ecosystem is alive and well and newer iterations of Java EE have been giant leaps forward in terms of productivity.


Java isn't a bad language, but the point is that it doesn't offer much what other languages don't. It's unique selling point is that it is there, and that it's widespread.

Said politely, Java is “conservative” to include new features. Take for example lambdas, which make writing async code, inversion of control, and yes, functional programming much more easy. All modern competitors to Java have lambdas: C++11 and C# (LINQ! need I say more?), plus basically everything except C. Java 8 has still to ship. A more flexible object system, e.g. using traits, would not be impossible to implement, but I doubt this will show up before C++ has them ;-)

Ecosystem? Well, that is a good argument, but other languages have ecosystems as well.


Well, interfaces with default methods in Java 8 are a form of traits.


this. lisp is 50+ and still the most syntactically awesome thing eva.


OK. Nobody is trying to sell how Lisp "rocks more than ever" and is the great new style.


My point is that Java isn't the new hotness and it's ridiculous to sell it that way.


Ruby’s 20. Just FWIW.


More like Why Stadium-Scale Sound Systems Rock (even if you play shit music on them).

JVM != Java


Oh, absolutely, but even the Java language is quite fine. Even new languages like Go and Dart are essentially modified forms of Java, and Java 8 is a welcome improvements.

Those programmers who like the Java gradual-improvement philosophy and find Java 8 lacking, should try Kotlin.

Others who want a truly beautiful, elegant and modern language, should try Clojure (and for those who like Haskell but find it too easy, or prefer a truly complicated language with a lot of power but no coherent philosophy whatsoever other than a collection of lots-and-lots of haphazard features – there's Scala ;)).


As a Java fan I claim that Java is the best choice for lots of projects. What other language has:

- amazing tooling

- static typing

- great performance

- huge amount of libraries available

- multiplatformity

?


All this is only worsened by the ‘black box’ nature of the optimization level switches.

Doesn't the JIT do all sorts of crazy stuff that's not always reproducible and thus hard to profile? I know this is the case with V8, but probably also so with Java. I don't know much about compilers, but the author seems to know even less.


The author appears to be laboring under the assumption that enabling GCC or Clang optimizations can cause failures in programs, in contrast to Java where the guarantees are rock solid. Of course, this is not true- in both Java and C++ the compiler's optimizations are strictly standard-compliant (at reasonable O levels in GCC) and in both if you rely on undefined behavior then optimizations can break your application. His problem isn't with unreliable optimizers, it's with writing bug-free code.

And yes, HotSpot can do tons of stuff, from eliminating virtual method calls, to inlining methods, to deciding whether a wait should be busy or not. And it does become a serious pain to profile, especially when you have code paths which are infrequently hit and so might not be JITed.


Sure, but the number of ways to (accidentally) rely on UB in C++ is order of magnitude higher than in Java.


I don't know if the whole oracle/sun debacle is to blame for the complete stagnation of the jvm and the java language, but the development pace is laughable these days. We're still waiting for proper lambda expressions after all these years. We still have a runtime without generics. And so on.

The irony of the article is that ZeroTurnaround not only make money from the java community, but does so by selling tools that work around shortcomings of the jvm. So not only is it in their interest to have a large dev community on the jvm, if you are a bit mean you could say its in their interest to have a crap jvm :)


I never understood what's the big deal about runtime generics. It's clear that some minority of people thinks that it's so important that it's almost the sole reason why "java sucks", but it's just a tradeoff that's decision that is controversial at best, with lots of people being completely happy about that.

For lambdas, I agreed though. Also, basic type inference, at least in a form already provided by project Lombok, is still sorely missing.


The type erasure is just a bad match with what's essentially a quite weak type system withq few other design flaws in it. Had the type system been good otherwise, it wouldn't have been that bad, but the way java works with for example array covariance and so on makes it a poor design.

That, and of course the fact that all AnyCollectionType<T> should work with primitive types without performance penalties. Having to use an MyFancyIntTree rather than MyFancyTeee<int> is a bloody disgrace.


This article didn't impress me, but from the author's bio sketch I was led to look up the eigenharp, which did.


I rather much thought that "DLL Hell" was a solved problem. I haven't had to worry about DLLs on my Windows box in years, basically since Win2k an XP.


Depends, for some no: http://www.drdobbs.com/windows/no-end-to-dll-hell/227300037

I think some form exists even in Java, software is hard at times, it's just the nature of a complex computer world that doesn't play by the rules of any other industry.


Old-school Java programmers are familiar with JAR hell during deployments with simple, naïve classloaders that just pick the first JAR with the desired class in it and don't provide versioned separation and ignore manifest files. The legacy solution is to write your own classloader and to use facades to get the correct class dependencies loaded more or less. JARs with correctly written manifests help but a lot of the Java convention system is not well adhered to even with widespread tool support. It's solved in modern app container based deployments of Java webapps at least.


Java is the definition of enterprise level language. Very newbie friendly. It's nice for the newbies but it's verbosity and small set of features kills it for any experienced programmer.

Please don't tell me about the fabled Java 8. Google doesn't care about new java versions, so we are stuck with Java 6. Most people will move to other languages until Java 8 gains any traction.


The author forgot to state in his title that he compares Java to C/C++/Objective-C languages (he does state it in the comments though).

In this context the article is a joke. Java Rock More Than Ever, my ass! The author compares one old technology to the other old technology using a 10 year old list of features.


A more interesting question is how much other languages rock in comparison to Java.

(As I was in the middle of this reply, the Java Auto-Updater popped up and stole my focus!)


Argh. You can't use Open Sans Light as a body font...


For those of us who don't know fonts, can you explain why? I'd like to avoid making a similar mistake, and I wasn't bothered when reading the article.


Light fonts are for accents or headers, not for body text. The body text should be normal weight and, in my opinion, should not be #5F5F5F either. That is unnecessarily punitive to the reader.

Here is an image comparing the original on the left and a corrected version with black text in a normal weight on the right. Note how much easier the right side is to read. http://i.imgur.com/WMJ8zcG.png


Typically any "light" font weight is intended to be used at larger sizes, often as part of headings. Using it as the body font will make your text harder to read unless you're using a very large font size.


It's thin and hard to read.


like a university professor, dusting off some old notes for a 'new' lecture. Students are meanwhile doing crazy exciting stuff out there.


while the university professor earns per month what the students get per year.


Note that the debugger (jdb) isn't listed -- for a good reason. I never understood why jdb is so poor being such a critical tool.


Reason number 1 to get an IDE for Java. Having a working [c/e]-tags replacement would probably be reason 2.


Oh, shucks. I was expecting to see an article on compiling Java to machine code, not bytecode.


Just look for a compiler design book.

Compiling some form of bytecode into machine code, is part of any compiler design course worth its name.


Java as a language is not that great, but the alternatives are usually even worse:

- Python: slow, dynamic typing

- Scala: slow compilation, very complex syntax, worse tooling,

- C#: MS-centric (but other than that C# is superior to Java)


Not sure why you think that C# is MS-centric. There is nothing about the language that is particularly MS or Windows specific and the .Net Framework was written to be general and cross-platform.


My impression was that e.g. support for multiplatform GUIs or Mono's speed wasn't as good as Java.


Mono's speed is a valid point, but I think that's more of a Mono implementation issue than a C# problem.


Yes, C# as a language is without question better than Java but in terms of the whole ecosystem, it's not that clear...


Mono does not provide support for some stuff like WPF, for example.


this title makes me giggle.. ok, I know...I'm too lazy to even open this link..




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: