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.
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.
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.
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.
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).
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.
> 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.
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.
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.
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.
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.
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.
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".
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.