Part of the answer is Java itself. It's verbose, static typed, and requires a lot of boilerplate code to do properly. The fact that classes are a compile-time concern, rather than a runtime concern, is just such a drag. You end up with interfaces you don't really need, only so that you can inject them into constructors so that your app is properly decoupled and testable.
Part of it is a framework issue. Struts is horrible...absolutely, stunningly horrible. Your controller is an XML file (seriously). Freemarker (the main templating language) makes ColdFusion look awesome.
Play is better, but it seems built for the way websites were created in mid-2000. JSON is still a second-class citizen. Static actions are a weird choice given IoC is achieved via DI in a static language.
Edit: I should add that there's also the persistence story. Anyone who's done [n]Hibernate knows that it's, at best, a mixed blessing. Even Java's NoSQL drivers are verbose compared to their dynamic brothers (first-class hash support is a big issue here, for some drivers in particular). I'm not sure something like Sequel would even be possible to write, and the AR implementations are, again, limited by the compiled-time nature of the language and the inability of bend the syntax into a nice DSL.
Java also lacks lambdas, and generic support is weak. And what's up with int vs Integer...the list goes on and on.
I think you need to reconsider your views regarding play. Version 2.0 has been a major improvement regarding a lot of issues. Asynchronous Requests are inbuilt as well as Websockets. (And Json serialization is as easy as Json.toJson())
I agree that static controllers are not always ideal considering that Java does not support inheritance of static methods, but the arguments of why static controllers are chosen can be found here: http://stackoverflow.com/a/5193721/616974
Still I think that developing with the play framework is a very productive process and can be compared with the likes of ror/django etc with the benefits of type safety all the way (including the templates)
I did look at 2.0 when it came out, and I'm under the impression that you still need to write a custom binder. Just now I tried to look it up, but the documentation points to:
...and that is why the latest generation of JVM languages such as Scala, Clojure and Groovy are so popular. Java the platform is extremely stable, highly optimized and heavily instrumented. Java is much less verbose than C++ (the main alternative when it was released), but the times have moved on.
With Scala statically typed and verbose are not synonymous. Statically typed = high performance. Type inference and compact syntax = expressive. Best of both worlds. Languages like Ruby bring expressive syntax, but performance suffers. Performance is becoming increasingly important with mobile applications, one of many reasons Ruby adoption has stagnated since the end of 2010 (see open source contribution and indeed.com charts).
There's no advantage to the need to over-architect. It's purely a bi-product of Java (or static languages in general). Because you can figure out how to properly write a Java program doesn't make you clever, sorry.
C/C++ programmers moaned about Java and garbage collectors the same way Java programmers are moaning about dynamic language.
Static languages have some advantages. It's not quite the same thing (Perl being dynamic and all) but I have gone towards Moose in Perl which gives some of the things I see as advantages of static languages (such as the ability to engineer in constraints declaratively, assuming those are enforced by the language. SQL is great this way.)
The real reason to use languages like C and C++ is performance. The reason for dynamic languages is rapid prototyping. Java is somewhere in the middle but not really ideal except for where you want to compile your software to run on an imaginary CPU which can be emulated everywhere :-)
I'm not saying they don't have their advantages. I want to be clear about that. But for most web apps, the limitations probably outnumber the benefits. Especially since the stateless nature of most web apps allow for easy horizontal scaling, thus negating the performance advantage.
As for performance, it really is amazing how fast node.js is. It's like a slow static language rather than a fast dynamic language (by that I mean, the gap between it and Java is smaller than the gab between it and Python). I don't know why that is, but I hope every dynamic language has that potential and that someone manages to unlock it.
I think there is a more fundamental reason. Java, being a compiled language that has traditionally aimed at compile once, run anywhere, offers a significant overhead, but with a development speed of a compiled language. It may or may not be faster to write code in Java vs C++, but it's certainly way faster to write code in Perl, Python, or Ruby.
I have always felt that Java was ill-suited to web applications generally, and that the main advantage of using it for web apps was being able to make use of third party libraries written in it. In this regard it's kind of like "why would you write your web app using DCOM on Windows?" Well, maybe because you are recycling VB logic from desktop apps?
> So basically, it's due to lazy programmers who moan if they have to type or think too hard.
Typing is a problem. Thinking too hard? Where does the OP imply he is averse to thinking? Being turned off that "fucking XML files are controllers" is being averse to thinking?
> Also very very much fashion lead by hipsters who must be using the newest coolest untested thing on the planet.
And those untested things would be? Rails is untested? Or Django? Or Flask?
XML has absolutely nothing whatsoever to do with Java the language. Some frameworks might use XML. There might be some built in functions/objects that deal with XML. But that doesn't mean you have to use XML. I certainly haven't in the 12 years I've been using Java.
> XML has absolutely nothing whatsoever to do with Java the language.
Weren't we talking about what OP said, and how per you, it's being averse to thinking?
> Part of it is a framework issue. Struts is horrible...absolutely, stunningly horrible. Your controller is an XML file (seriously). Freemarker (the main templating language) makes ColdFusion look awesome.
Now if some framework has achieved this level of retardation, I would rather not think about it. There are better things to think about. I would be absolutely fine being averse to thinking about it.
The OP asked why Java isn't used for the web. One of the more popular Java web frameworks heavily relies on XML. It has nothing to do with Java, but it has everything to do with what the OP asked about.
You can have a pretty good Java web server going in about 200 lines of code.
No, you can't.
Your "simple HTTP server" proposal is roughly on a par with suggesting that a web developer should design his own security protocols. The idea is simple enough, but there is a lot of subtlety involved in covering all the edges cases properly, and a lot of very smart people have spent a lot of time building, testing and maintaining good tools for these jobs. Why would you reinvent the wheel, with a flat edge across part of it, a single spoke connecting to the axel, and in only one size that won't be the one that fits under the arch next week anyway?
XML may have nothing to do with Java, but some Java frameworks (e.g. Spring) are obsessed with it. Many (most?) Java devs don't even like Spring. Who in their right mind would want to write code to call constructors in XML? no type checking, no refactoring support etc.
I suspect the main reason Java became XML obsessed is because MS came out with C# and bragged about their XML and web services support. Ever since then Javaland has gone out of it's way to prove it was more XML and webservice centric. Net result is Java devs writing XML instead of code.
Actually, with Java, I type more than I think. A lot more.
Compare this to Haskell, where a single keyword might involve substantial thought, or APL, where one character more or less could represent a pretty fundamental restructuring of part of the program.
That Java makes you repeat yourself is not controversial. That being averse to this means you dislike thought is a somewhat bizarre position to hold.
> That Java makes you repeat yourself is not controversial. That being averse to this means you dislike thought is a somewhat bizarre position to hold.
The English language makes you repeat yourself. I don't see it as a bottleneck. I've never considered <speed of typing> a bottleneck to programming. possibly when programming some assembly routines. But if you're typing too much, you're probably repeating yourself too much, which means you're doing something wrong.
Things that can be libraries in other languages end up being "design patterns" in Java. It's just not flexible enouth, both Ruby and Haskell are more flexible than it. Both in different ways.
In Java, I type too much every time I have to deal with the fact int and Integer are two different types. That's a design flaw in Java, not in anything I've ever written using Java. And that's just a trivial example off the top of my head.
> why does a language designed around an OOP perspective need a lambda
Because only through lambdas can you actually do OOP: a core of OOP is to tell objects to do things. That you can do with lambdas, through customizing "the thing". Without lambdas, you are left with the requirement to painfully and painstakingly get bits and pieces in or out of objects in order to do the thing yourself, ending up with a horrendously procedural language with a smattering of objects added on top.
Now think of how to write that code not using lambdas.
In Java where people seem to like typing unnecessary stuff it would make sense to not have lambdas as then you can type extra stuff. Also lambdas would reduce KLOCs thus making teams using java with lambdas less productive.
This is similar to the reduced productivity seen by teams using scala or clojure on the JVM.
Also, OOP has nothing to do with procedural or functional languages, it's completely orthogonal.
Purity is orthogonal to lambda abstractions. It's matter of what function can do (pure or not) and function creation (a lambda or something more verbose).
>Part of it is a framework issue. Struts is horrible...absolutely, stunningly horrible. Your controller is an XML file (seriously). Freemarker (the main templating language) makes ColdFusion look awesome.
Play is better, but it seems built for the way websites were created in mid-2000. JSON is still a second-class citizen. Static actions are a weird choice given IoC is achieved via DI in a static language.
99% of websites are still built "the way they were built in mid-2000", and there's nothing wrong with that way.
Client-side rendering and such is not the "new way", is just an alternative way for certain types of websites, that is still quite immature and can take you to a world of pain if done bad (see Twitter).
My complaint isn't about client-side rendering. It's about _anything_ that involves getting in JSON or outputting JSON. It's essentially being able to easily bind json to objects on the way in, and being able to use respond_to and to_json on the way out.
"public static void main()" isn't a lot of code. It's three keywords, and one identifier. You may consider it a lot of characters, but it's pretty rare that a programmers bottleneck is speed of typing.
I wish people would stop confusing "number of characters" with "amount of code".
And FWIW, I find your example far harder to decipher. I have to know what => means, # means, what : means, etc etc etc.
Add to that, in your example, if you typo one of those characters, your code may well still run, but will fail. With Java, if you typo a single character, it's more likely the code just won't compile.
We could all code in regular expressions or something akin to that, maybe perl one liners. But "number of characters" isn't a good aim. Readable, maintainable, well written code is.
The last part of your comment is just language bias. symbols and hashes are fundamental to ruby. Why would I use string concatenation like my parent, when the language support string interpolation. It's as unclear to you as generics or annotations might be to someone who didn't know Java. Surely you see that?
I think you are being pedantic about characters vs code. But, for what it's worth, I disagree. You are having to create 2 classes, define a field, a constructor and use four framework specific annotation. I consider all of that code (made up of characters).
Both versions should be unit tested. The unit test might be more important in the Ruby version, but so too will it be easier to write.
I grew up reading assembly code listings. Being able to read code is a really really important skill IMHO. Something like Java is very very easy to read. It's mainly keyword based, rather than special character based. I'd much rather read a 1,000 line Java program, than a 100 line <concise language> program.
The other point I'd make is that Java is probably about as verbose as english is. But we all manage, using English. We don't moan on and on that talking, writing, reading is so inefficient and we should all switch to something better. English also has odd grammar and spelling rules which are inconsistent and plain stupid sometimes. Yet, English works pretty well for what we use it for. Communicating.
You'd much rather read a Java program because you are already biased towards it. Yes it's easy to read, but you need to acknowledge that many other skilled developers would find it easier to read Python, or Ruby, and indeed would rather read 1,000 lines of the same over 100 lines of Java. Otherwise you are simply being willfully ignorant.
Why is Java considered inefficient and English not? Maybe because we don't need to create a new class for every concept in English. Yours is a pretty poor analogy; English vocabulary is extensive but it is not inherently verbose.
Anyway I am only writing not to say you are wrong, but rather, since other people are arguing with you reasonably and you are dismissing them without consideration, your argumentation is wrong.
"An unordered tuple Z going from a1 to an is a defined as for every x in Z then x is a1 or x is a2 ... or x is an"
than
"An unordered tuple Z (a1,...,an) is defined as [x : x = a1 v x = a2 v ... x = an]"?
I take that as not being (or not wanting to be) familiar with the language you are reading. If you'll read Ruby, at least browse a manual to know what {} and # mean.
The psuedo-Ruby code posted there is characteristic of someone who is having a knee-jerk reaction against something they don't understand. The person we are arguing against is obviously a Java zealot that will never consider using another language, so as long as he's going to accept that different people like different languages I think that's good enough for today.
The other point I'd make is that Java is probably about as verbose as english is. But we all manage, using English. We don't moan on and on that talking, writing, reading is so inefficient and we should all switch to something better.
You've made this argument in multiple posts now, so I'm just going to point out here that people doing science and engineering use formal, mathematical notations precisely because they do offer more precise and concise ways of expressing the necessary technical concepts.
There are plenty of reasons to criticise some of those notations with hindsight, but "not being English" is not among them.
This is just a sad Stokholm defence - against languages that threatens your sacred cow - which is understandable since the Java code example got pwned.
So rather than defending the code example on merit, you dive into pedantic nit-picking territory. I used to be defensive about my choice language as well, till I matured and realized holding onto sacred cows just hurts your ability to learn from others doing it better and being more productive; and just clouds your ability to choose the right tool for the job.
More code = more code, to read, to decipher, that hides intent, that adds complexity, that can have bugs and can go wrong. Code-size is codes worst enemy.
I don't even know Ruby, but it's implementation is vastly more readable and would look a lot closer to what the perfect DSL would look like for this task, than the Java example.
The sibling comments point out some good points about your general critique, but it's worth noting your code isn't really "equivalent"; almost everything you chopped was a datatype declaration, which isn't required in Java any more than in Ruby:
@GET
public Map<String,String> greet(@PathParam("name") String name) {
return singletonMap( "content", "Hello, " + name );
}
I like both of these systems, and Java is undeniably the more verbose language, but this framework really isn't an egregious example of that.
I've been trying to ignore this particular flame-war, but your example is doing fundamentally less, because it's not binding objects to json (which was what you originally asked for).
I actually cannot write your example easily in Sinatra/Ruby/etc, without making my object either a Hash or an ORM subclass, customizing serialization, or pulling in uncommon libraries.
Here's your complete example, in reasonable Ruby. It's longer than the Java.
class Greeting < Struct.new(:content)
def content
"Hello, #{super.content}"
end
def to_xml
{:content => content}.to_xml
end
def to_json
{:content => content}.to_json
end
end
get '/hello' do
response = { :content => Greeting.new(params[:name]) }
respond_to do |wants|
wants.json { response.to_json }
wants.xml { response.to_xml }
end
end
If I create an imaginary library that does exactly what we'd want here, it'd look like the following. It's marginally shorter than the java, but hard to argue anything about it being fundamentally better.
class Greeting
include JsonObject
field :content
def content
"Hello, #{@content}"
end
end
get '/hello' do
response = { :content => Greeting.new(params[:name]) }
respond_to do |wants|
wants.json { response.to_json }
wants.xml { response.to_xml }
end
end
That's a funny complaint when evaluating 4 lines of code one of which is end.
Java makes the assumption that you need a lot of boilerplate code, so being able to make changes easily seems like a big deal. Other languages avoid that boilerplate and can make the changes just as easily for free.
Making changes to a complex system is a "big deal" in any language. Pretty (and compact) syntax doesn't help much, especially when the refactoring tools are weak.
Its fine code once the design its settled, but while you're changing the schema, the backend java code and the frontend javascript, having to change all those classes gets tedious.
Part of it is a framework issue. Struts is horrible...absolutely, stunningly horrible. Your controller is an XML file (seriously). Freemarker (the main templating language) makes ColdFusion look awesome.
Play is better, but it seems built for the way websites were created in mid-2000. JSON is still a second-class citizen. Static actions are a weird choice given IoC is achieved via DI in a static language.
Edit: I should add that there's also the persistence story. Anyone who's done [n]Hibernate knows that it's, at best, a mixed blessing. Even Java's NoSQL drivers are verbose compared to their dynamic brothers (first-class hash support is a big issue here, for some drivers in particular). I'm not sure something like Sequel would even be possible to write, and the AR implementations are, again, limited by the compiled-time nature of the language and the inability of bend the syntax into a nice DSL.
Java also lacks lambdas, and generic support is weak. And what's up with int vs Integer...the list goes on and on.