1. JSP
2. GWT/GAE/AppScale
3. Play
JSP is just awful - taking PHP and trying to fit it into Java somehow. It's just terrible and needs to be phased out ASAP. (EDIT: Probably too harsh.. JSP works in the same way PHP works: it powers most of the web, and it does a grudgingly good job. The ease of plopping in some dynamic content into am html website made by a designer should not be discounted lightly for small websites. Probably best to just use PHP and not JSP in this use case though...)
GWT/GAE/AppScale mix is my preference. You can share code across server and client. Building RESTful services is a dream with Jersey on the server/thick client, and RestyGWT in the browser. The GWT compiler produces some very well performing javascript (only a bit slower than highly optimized libraries, but feels faster than nearly all webapp javascript). GWT also has incredibly good tooling support in automatic sprite sheet creation, compiled CSS styles, uibinder for declarative layouts, etc. The downsides are (1) java language, so no functional programming and (2) compile time can get nasty when you head in the millions-lines-of-code arena. GWT team is seemingly working on speeding up the dev cycle with SuperDevMode and that.
Play framework is most similar to the ruby on rails approach and works incredibly well for your standard webapp. The support for Comet and WebSockets are particularly nice and making very dynamic 'push' webapps is the real strongest point. The tooling can get pretty annoying at times with features/bugs, but it is steadily improving. The biggest downside to Play is that it is in a 'hipster phase' currently with the release of Play 2. This means both a huge surge in interest, but that same surge can be a curse when it drops out of 'hipster' mode in the future and loses devs. Numerous promising frameworks/languages have hit this problem and never really recover when the 'fashion' changes.
GWT, for example, has long since fallen out of fashion but continues to be heavily developed because of the huge and profitable existing user base inside Google (Adwords, etc), guaranteeing it active development for awhile to come.
(1) The ubiquity of the Java/JVM ecosystem paired with the interest in a alternative to Java will keep the functional JVM Langauges like Scala/Clojure in high demand.
(2) The Typesafe machine pushing Play (see http://blog.typesafe.com/typesafe-announces-14m-series-b-fin...).
(3) Scala is your best bet for a Statically Typed Functional JVM language. Also, we use Play 2.0 at the startup I develop for.
I also find that Play is pretty cool to work with. Gone are the days of having to use servlet containers for development.
It is ABSOLUTELY a pleasure to use. I did a thorough analysis of all the Java frameworks that I could use and Play is what I landed on. It gets out of your way and if you use an IDE like IntelliJ IDEA - you will develop on the same speed with something like Django or Rails.
Play has made me really enjoy Java again since during our CS courses and my time as a high frequency algorithmic developer on Wall St was spent in C++/Python, I never needed to really use Java.
Now, I can tell you that I have new found respect for Java and I can't speak highly enough about the Play framework. I'm happy to elaborate a bit more on our use of it -- feel free to contact me via email in my profile.
Why? Since it's in the official typesafe stack (a company founded by Scala's creator to promote it and it's ecosystem commercially), based on concepts taken from RoR, has rapid deployment without the need to pay JRebel 100$ per developer, and is supporting both Scala and Java.
So I see it as "finally something good happening to those who wait". It's the only way enterprises can start doing modern web development without giving up on their existing investment in the Java / Spring / Hibernate stack. My view on it? I can't wait to get a work related project done with it.
Lift is also an interesting option (Scala only though), but you asked about Play. Lift has it's learning curve, but it's creator claims it is better than Play in almost any aspect, and many tend to agree, but I don't know enough to judge...
The "the-view-is-the-controller" approach encourages a messy blend of logic and presentation, with lots of HTML ending up in your Scala code.
It's stateful in the extreme, using opaque callback identifiers to identify serialized closures, so rather than having a nice, clean, easy to reason about boundry between your app and the outside world (your routes file, controller methods, whatever), any code anywhere could be invoked by someone clicking something in their browser.
Validation now needs to be enforced in the models, since you no longer have a single place to check it as it comes in. It goes beyond that and embeds rendering logic in models, which have to toForm method which generates HTML.
The extreme statefulness also means you lose everything when you roll a server, you need sticky sessions, you spend way too much time GC'ing and you need far more RAM/user.
Bummer. I'm using scala at a small startup.
I'm not asking about language semantics since I believe that to be a personal preference, rather scalability and performance.
If you start with such patently false beliefs you aren't going to get anywhere. Good abstractions are good, regardless of your personal preference. I have a very hard time programming without immutability, catamorphisms, pattern matching, sequence comprehension, varargs, fmaps/functors, partial functions, monads, predicates, filters, higher order functions, lambdas, closures, trampolines, continuations, strong types and co/contra-variance, options, actors, immutable collections, regex, combinators ( kestrels ), a dash of abstract algebra ( monoids semigroups groups rings fields ), basic math structures ( at a minimum, graphs with traversal algos baked in ), macros, implicits, dsl capability, and a mathstat library.
If you give me a language without some of the above, I will first invest time buying/building whatever is missing, so that I get that full list.
The claim is that scalability is an acronym for that list. If you give me everything in that list I give you scalability. Scalability is not about being close to the metal, gobs of ram etc...rather we are talking about the same block of code that services 200 million clients with the same sla/latencies as easily as 200 clients when you throw reasonable extra horsepower at it.
Without that list, you are essentially programming in the 19th century. You will, without even knowing, end up building various versions of these in your own pet language...for example, after writing a "for loop" with an "if statement" to vary behavior based on containment in a collection for the 100th time, it will occur to you that there must be a better way to encapsulate this logic...and sure that's what a predicate with a partial function is...but it's not like you are newton and you sit under apple tree and apple strikes your head and you get gravity out of it...these things won't come to you like magic...you have to essentially sit down and read a book on fp where they tell you why they do what they do.
The thing with scala is that you can pair it up with akka/breeze/scalaz & hit every single item on that list and then some. So also with haskell, clos, ocaml, sml, clojure, erlang...the match degree varies but you can get close to 90-100%. If you try to hit that list with a non-fp lang like c++/java...the degree is like 20% and you will have to do 80% of the work to hit that list.
Now you could say (as my manager at my former big-co did) I don't give a shit about that list above, maybe your list consists of only 3 things - personal preference, easy availability of devs from india for hiring purposes, and spending less money. Then sure, java is on the table, as is js, ruby, python, some subset of c/c++ etc.
The higher level abstractions that are directly supported by Scala are precisely what make it more "scalable" from an authoring perspective. In particular, the amount of help it provides in writing many objects to support an OO design along with the functional support it has go a long way to reducing your code down to quickly communicating the abstractions you are using, and not the language used to describe them.
This is particularly true in a method body, where one can use inference to remove the types from the code rather well. With judicious use of map/etc, often changing the collection type you are using is reduced to a single change in the code, and not through every intermediate collection along the way.
I've never really seen the benefits of Scala. Everyone whines about Java syntax, but it's really not that bad. Verbose, sure, but it just doesn't seem like time spent typing is where my productivity goes. Maybe I'm just getting old, but I no longer care about language syntax as much as I used to. A preprocessor to give me Java 8 lambda syntax would probably solve all the issues I have with Java right now.
That's one of the things that Scala gives you: the functional features are there now and have been for almost ten years.
Still, I know where you're coming from. I was a die-hard Java guy until I gave Scala a shot. I'm not looking back, though I do think that Java's tooling is much more mature than Scala's.
Code becomes a lot more clear, explicit, and... fun. I recently talked to a dev who used Akka with java for a network server, and he ended up coding it in 'an object for each callback handler' style.
When I asked why he did it that way, he said nesting callbacks to sequence operations would get too ugly fast.
This is trivial in scala. The language flaws in java ended up dictating the architecture of his entire application, and for the worse IMO.
[1] https://en.wikipedia.org/wiki/Scala_(programming_language)#C...
https://jazzy.id.au/default/2012/10/16/benchmarking_scala_ag...
Since it's all just bytecode, then there's no difference in what you can do when it comes to scalability. However, it's the semantics, that you think are just personal preference, of Scala that make writing scalable code easier, it biases you towards scalable code with things like default immutability and using asynchronous io and things like that. Anything you do in Scala you can do in Java, but the question is, when the syntax overhead of for example monadic programming is over 5 times greater than the equivalent scala code (and many times less readable and maintainable), would you do that? Most developers don't. I wrote another blog post about that here:
http://jazzy.id.au/default/2012/11/02/scaling_scala_vs_java....
You can still have the exact same Futures functionality in Java, but they will be so much more verbose and annoying to use that it ends up not being a good idea.
Someone already mentioned immutability. Another example is sound concurrency support: a language which is using non-blocking synchronization is not going to have threads constantly blocked monitoring locks (I'm not talking about Scala particularly: but in Java the language, the "synchronized" SNAFU is really totally messed up if you've done any serious concurrent programming and it's very hard to get "right").
Then another example it's also a fact that crazy optimization can be achieved by using macro pre-processing at compile-time. Java the language doesn't offer this. It's actually so problematic in certain cases that there have been specific tools developed (e.g. by Nokia for accessing the J2ME Nokia API) that did add macro support to Java.
Another example where macro do shine: an API like trove, using primitives-backed maps/set, runs circles around, say, a normal HashMap{Integer,Long}. But Java cannot automate/duplicate the code needed to offer this for all the primites types (which, some may argue, is precisely the reason why such performant maps/sets have never been part of the stock Java APIs). So how do you do if you want to "run around circle" of these default totally lame HashMap{Long,Integer} like if you're say, the Trove author? You write your own code generator generating all the .java files needed from a template. Pretty cool (from the Trove author) but also pretty lame (from "Java the language").
With real macros this one is a no-brainer. So much for "semantics".
These are just two examples: you're belief that language differences can be resumed to semantics is incorrect.
- What kind of tooling do you use? Which version of Scala?
- Any tips around hiring and ramping up a team?
Thanks for the offer.
Edit: formatting
* [not] loading a lot of session data on every request
* storing data across shards
* parallel processing
* a services approach
Wow, I think something is over-architected.
Curious: does exponential growth mean 2 concurrent users to 4? If they have more than 100 concurrent users, I would be highly skeptical.
And, if they can't solve that problem with any language, I would also be highly skeptical.
https://www.lucidchart.com/blog/2012/10/31/500000-chrome-web...
Even with 550,000 installs there, the Chrome Web Store is just one of a number of strong channels for Lucidchart and contributes a small minority of our user base.
That said, i have my doubts about the term 'exponential'. I forgive financial journalists who think that it means the same as 'explosive', but a programmer should know better. Unless, of course, Lucidchart does have exponential growth, in which case i guess congrats are in order.