I used Play! for more than one and half a year and I must say I have mixed feelings about Play! now. Before 3 or 4 years ago, your chances with getting a web application easily in JVM languages was using J2EE ecosystem or Spring framework. But now there are plenty of alternatives. When Play! came out, it has done really a good job, it was working just fine, it was magical and it totally nailed it. But then frameworks evolved around languages like Groovy and Clojure and they nailed it as well. Best move Play! made so far was supporting Scala, because all existing Scala web frameworks were crap (yes I'm talking about Lift).
I used Play in a startup backend and I won't be able to say I was satisfied with it. Play v2 is especially slower on your local development box, compilation takes some time and I actually still like Play 1.2.x family more. Its memory consumption was horrible on production (I made really a lot jvm adjustments and could not get it properly).
Personally, I now like Python frameworks (e.g Flask) and they are much easier, but I am not sure if you should rely your whole service infrastructure or enterprise software on a dynamically typed language stack. There are companies out there achieved this but I think Java or Scala will be just fine for LinkedIn, and by the way why the hack they don't allow comments on their engineering blog?
I spent quite a bit of time evaluating Lift for some fairly significant (2 man-year+) projects. My final conclusion is that while it is technically brilliant, and many of the concepts make a lot of sense, it's just very hard come up to speed on and be productive in, especially if you aren't already a Scala wizard. Any Lift project is likely to have a fairly low "bus factor" if you don't already have multiple strong in-house Scala folks.
I had some technical concerns as well - in particular the database connectivity stuff is a bit painful.
Hmm.. I'd never heard of the term bus factor. Amusing concept. How do you feel Lift compare with the likes of Play?
I can say that the few small things I pushed out with Lift greatly benefited from the fact that the views were strictly html. To the point that nobody else involved even had to learn scala. Even though they did make some changes to the scala code. Being able to let folks edit that to their hearts content was ridiculously nice. That is, the fact that I did not have to (a) educate everyone on the templating mechanisms or (b) split apart templates received from someone else was huge.
As for the database connectivity, I guess you didn't like the agnostic approach they took?
I can see how that's a factor for some, but since around here I'm also the guy who writes all the HTML it isn't really a factor one way or the other.
Re: Databases
Yea, ActiveRecord tends to spoil one. I don't like any of the Java ORMs nearly as much as AR, or SQLAlchemy for that matter.
Re: Play
I like Play a lot less than Lift. Lift I could see using for a personal project. Play I could not. It's just like Rails but crappyier and with all the java headaches and baggage.
As someone who's just learning lift, it's woefully underdocumented. You can do some really cool stuff with it, but learning requires scrounging tutorials from random blogs, and it then turns out half of them are out of date.
Templating wise the Wicket approach is the best I've ever used, and I wish that style was available in other languages. You don't put any logic or control in your templates; your object graph in code controls your page hierarchy, your components are genuinely reusable objects.
Yeah, I should have mentioned Wicket (it is credited as an influence for lift, after all). I can't remember what made that so difficult to work with. I think it was because you had to effectively mirror the template in code at parts, if I recall. As I noted somewhere else, the lift way of more directly manipulating the template is what I like. (That is, I don't have to have a ton of "liftId" attributes added to the template. In general, I just need the base class attribute added, and then I can manipulate the template using css selectors. This does mean some shape of the template has to be preserved, but I haven't found that limiting yet.)
There's nothing unique about lift's template system though, you can get something like that in many languages, potentially while also using a good framework.
I have not seen another templating system that compares. What other framework has it such that the templates are html. Not "html like" but actual html?
Honestly, I think for me the big win with them is actually the inversion of how the template is done. Instead of writing some template that specifies how it is manipulated, you write a template and then directly manipulate it in the framework. (That make sense?) In essence, it seems that it is automating the typical first task on getting some html from a designer. This is great, because often the template can be redone and then all of the modifications the programmer was going to make to them is just part of the framework.
As noted by TylerE above, I can see how this might not be a factor. I personally loved it.
http://en.wikipedia.org/wiki/Template_Attribute_Language is the most widespread example. We ended up switching to haskell and using heist, which is the same type of deal. The "view first" thing was certainly very irritating, but minor overall compared to other weaknesses in the framework.
Any better examples? Neither of those appear to have the same strengths I was referring to. (Not to say they are crap. Just not the same.)
Though, similar to TylerE, I'm curious to hear what you think are the other weaknesses? Similarly, how do you feel it compares with its peers? (A peer being a JVM targeted framework.)
I don't know what you are referring to. What strengths? They are html templates.
If you are going to restrict "peers" to jvm frameworks then I really can't offer you anything. I haven't used any other jvm frameworks, I tried the two scala options (lift and play) and ran screaming.
First, apologies for taking so long to respond. I almost just edited my other post. (For some reason the "reply" link wasn't coming up.)
Regardless. I see that the Heist language looks like early Lift templates. They got stronger with time. For the TAL stuff, it looks like logic is directly placed in an attribute. Probably both would be a far cry better than the stuff I have become accustomed to, however, Lift still seems stronger. Again, the difference comes in how the templates are "split" and placed in the app. The lift way just requires judicious useage of class names.
Moving past that, though, I'm still interested to hear an analysis if you are up for giving it. While I'm most likely to only understand what I called "peer" comparisons, I'm interested in all.
Edit: Further apologies in that I am likely not going to be able to respond for a while at this point. So, thanks for the discourse!
Stronger how? It is just a pseudo-html document tree being manipulated in scala. I'm not sure how it can become stronger or weaker.
>For the TAL stuff, it looks like logic is directly placed in an attribute.
It is placed wherever you want it. Using a TAL loop attribute is no different than doing the same thing in lift. The only difference is that lift doesn't show doing that in the docs, so people tend not to do it.
>Again, the difference comes in how the templates are "split" and placed in the app
I still don't understand what you mean. We literally took our lift templates and used them in heist just doing a search and replace s/lift://g. We just had to change the scala code "snippets" to be haskell code "splices".
>I'm still interested to hear an analysis if you are up for giving it
Lift assumes too much, and if you go outside those assumptions you are basically stranded. Combined with just being an immature framework where there's things missing/incomplete, and an outright hostile community, it makes things pretty difficult. Form handling was the biggest sticking point, especially when you want to have forms that aren't protected by their CSRF tokens and need to work with cookies disabled. It becomes a case of "well, we don't want to support that so just do it yourself from scratch".
Play we had tons of issues with the weird scala templates they use. It would barf frequently on what appeared to be perfectly valid syntax. Combined with the "developing with play is super fast!" sales pitch, while being slower to recompile than lift was, we didn't bother spending much more time on it.
I should have made clearer that I am reading on those template engines right off. That is, I hadn't really heard of them till you mentioned them. Asking for more was simply on the lines of "if you have other examples right off."
Regarding TAL. Looking at it, it did not look like it fed in the markup of the current tag to anything to process it. That is likely just my misreading of the wiki page.
Regarding Heist. This could again just be my hasty reading, I think. I saw it said it was the same idea as the Lift templates. But then it jumped straight into the bind and apply tags. With the latest lift templates, there are no custom tags. Nor are there custom attributes.
Also, I'm highly curious on the upsides of the Haskell framework you are using.
>That is likely just my misreading of the wiki page.
I would say the fault there lies 100% on the docs, not you. The docs are heavily focused on using the attributes that are provided out of the box, rather than on how to write your own.
>But then it jumped straight into the bind and apply tags
That's the equivalent of lift:surround. There's nothing special about those tags, they are just part of the set of default splices that you can use.
>With the latest lift templates, there are no custom tags. Nor are there custom attributes.
What are there instead? The docs still appear to be talking about lift:stuff tags and attributes. There aren't really custom tags or attributes in heist either, unless you want there to be. You are really just binding some haskell code to a tag or attribute. That tag could be a real html tag (like the splice included by default that is bound to the html tag, which consolidates multiple head tags into one). Or it could be a any tag you make up, like we bind a splice to the <user> tag which replaces the contents with the user data.
>Also, I'm highly curious on the upsides of the Haskell framework you are using.
Shockingly enough considering how haskell is known for slow compile times, faster compilation is one of the upsides. Mainly we used snap because it gives us the same thing we liked about lift (templates), but with no assumptions about how things have to work, a more helpful community, and a better language.
I think this does highlight the major problem with lift, which is just scattered documentation. The "designer friendly" templates push all of the lift:foo stuff into class names in the template.
That is funny to hear that haskell compiles faster. Seems scala is really becoming the language known for the slow compilation nowdays. I think there is some form of irony to that. (Though, I had not actually heard haskell was slow. I just know it doesn't target the jvm, which is where I've been living for a long time.)
>The "designer friendly" templates push all of the lift:foo stuff into class names in the template.
Oh, I realize you can do that also, I just didn't recognize that there's any difference. <lift:foo> and <div class="lift:foo"> are identical right? Heist lets you do both too.
>That is funny to hear that haskell compiles faster.
Not in the general case, but specifically with snap. I'm not sure what magic they have going on in their dynamic loader, but it is much faster than the one yesod uses for example (another haskell framework).
The difference is pretty much strictly whether it can validate and generally display correctly. I seem to recall browsers were less than good about the tags, whereas just having the classes works great to bang away at a template, and then use it.
Cool to see that Heist is effectively the Lift templating system. I suppose I shouldn't be surprised to see some movement in that direction. I do still for more templating like this in the jvm, though. I'll have to look into TAL more when I get the chance.
Of course, right now I'm having to use GWT for a project. Don't know why, but I loath UiBinder. And, well, most of GWT at the moment. :(
Can you provide any specific, actual, practical evidence that it is a bad thing to use a dynamically typed language to write a web app? Or is this just a personal prejudice?
>Can you prove your opinion is objectively correct, or is it just your opinion?
Doesn't that question seem rather non-productive? At least if you asked why he has that opinion you could engage in some sort of potentially constructive conversation on the topic.
Was excited to check out Linkedin using Play but then the reasons highlighted in the article almost let me down.
I am comparing to Python frameworks and Node and everything mentioned there has been available in the Python stack for a while and now Node (extra points for realtime websockets stuff).
As per the post Play boasts of:
Rapid iteration, Reactive (only for the server not the client), Open, Supported, Flexible, Java & Scala
Maybe I would consider Java & Scala just for the enterprise community scale but definitely not the only one for functional paradigms or rapid iterations.
Everything else is there in other modern web frameworks in Python, Javascript & even perhaps Ruby.
Probably a new thing for Java but why the choice? Is LinkedIn constrained to use the JVM?
LinkedIn is primarily a JVM shop. We believe that type-safe languages like Java and Scala are a good choice for building performant and reliable systems that scale to huge numbers of users as well as huge numbers of developers. We aren't constrained to the JVM - for example, we use node.js for our mobile server - but it has significant advantages and we have years of investment in it.
Unfortunately, we found developer productivity in the Java/Scala world to be a huge problem. We also found that most Java/Scala web stacks, based on servlets, were far behind other web frameworks (RoR, Django, etc) in terms of keeping up with the requirements of modern web development. Play helps on both fronts: it dramatically improves developer productivity and handles all the requirements of a modern web stack (MVC, web sockets, powerful routing, easy JSON handling, DRY form handling, etc).
Is it better than RoR, Django, Node? In some ways yes (e.g. Play's reactive programming model is dramatically better than JavaScript's callback mess), in some ways no (e.g. it's hard to compete with dynamic/interpreted languages for pure reload time). Is it better than everything else in the Java/Scala world? We think so.
With optional static typing you can pretty much pick and choose the best mode for each part of your application, which for me seems like nirvana. Even with static typing enabled, I find the syntax more concise and productive in Groovy than I do with Scala (I'm more experienced with Groovy so there's a lot of bias in that though).
LinkedIn has been using Grails for ~4 years. It's a terrific framework, but we found that Groovy was one of the downsides. The language is very easy to learn and use with Java, but we found that it didn't scale nearly as well to large numbers of users or developers. It's worth noting that this was pre Groovy 2.0, so I'm not sure what has changed in the latest version of the language.
Thanks - that's really interesting to hear. It sounds like your use predated 2.0, at which time I would certainly have said the same thing. However static compilation (a feature of 2.0) has definitely changed my feeling about it - you're getting compile time type checking and near-Java speeds, but all the highly expressive Groovy syntax still works.
> you're getting compile time type checking and near-Java speeds
The static compilation added in Groovy 2 is much faster than dynamically-compiled code but is still buggy e.g. http://stackoverflow.com/questions/14774709/groovy-2-1-0-wei.... It was written by one developer, and first shipped in Grails only 2 months ago, which doesn't even seem to use the static compilation features (correct me if I'm wrong). Let the Groovy/Grails developers eat their own dogfood first before recommending Groovy's static compilation to others.
Developer productivity is really broad. Can you elaborate? Most modern webapps I work on end up as json services and the backend are just java pojo services that can be unit and int tested - tdd with java is extremely fast in my experience.
the whole servlets/jsp/jsf thing is dead imo, is that where you guys were losing time?
We had Java services that produced JSON, some that used JSPs, and a variety of others. TDD works in some cases, but if you ever wanted to do manual testing - for example, actually see the UI you were working on with real data - that meant redeploying the server after every change.
Play makes this dramatically faster/easier. TDD is better with Play as well: the plugin support, strong test tools, and sbt's ~test command are amazingly productive.
If I were to guess, it would be configuration, more specifically the myriad number of choices and combinations of it. Spring's strength and weakness is the power of customizing it.
Our Play frontends are entirely reactive/non-blocking, so yes, we're using the async features very heavily. We'll have a blog post about this in the near future.
Our Play backends, if they use JDBC to talk to a database, are fully blocking, since pretty much all JDBC drivers are blocking. One of the nice things about Play is it's easy to configure the thread pool to handle this configuration as well.
Not really. I don't see what features Play Framework has that are revolutionary or things that no other framework running on the JVM/Java wasn't able to do before.
"Rapid iteration" is the kind of "feature" that every framework claims to allow. No one advertises they allow "slow iteration".
I believe The biggest differentiator in Play 2 is the reactive programming. Even if you look outside the JVM, NodeJS is the only other web framework providing that level of non-blocking http.
Rapid iteration is probably obvious for PHP, Rails or Django, but on the JVM (or .net), it's pretty rare to see a framework that really supports it well.
Right, but that's what I like about Play. They took Netty, and they took Akka and all the other really nice reactive stuff and integrated it very cleanly.
With Akka you get most of the concurrency benefits you would get from a language like Erlang, but with the benefits of having access to the entire JVM ecosystem.
To be fair, if a framework was totally uninterested in fast iteration or couldn't even remotely claim it, then they would simply say nothing rather than offering "slow iteration".
I could probably copy-paste this comment from any one of the many other Scala discussions where this has come up, but in short:
Scala isn't functional; Scala is proper (pure) OO in a way that Java never was. Scala doesn't support top-level functions (only singleton objects), which doesn't exactly prevent it from being functional, but certainly suggests that the primary paradigm is still object-orientation.
It just so happens that pure OO, when properly done, happens to embody a lot of features similar to functional programming - Smalltalk is the easiest example of this (eg. the similarities between Smalltalk message passing and Haskell's implicit currying are very clear).
The reason for this is that it's trivial to create a good object system in a purely functional language, so the FP-OO relationship isn't an either-or so much as a 'special case' (ie, OO can be seen as a 'special case' of FP). The converse isn't so true; it's hard and clumsy to build a truly functional paradigm within an OO paradigm.
What GP probably meant is that Scala isn't a good choice for those who are coming from an FP background, since they'll likely notice that Scala seems very OO by comparison (because it is). Even on the JVM, there are other languages (ie, Clojure) which embody functional paradigms more transparently. On the other hand, Scala is a decent choice for OO programmers who want to get a taste of functional programming (or who want to incorporate those paradigms into their code), because Scala allows several aspects of the FP paradigm to come through as well.
> Scala doesn't support top-level functions (only singleton objects)
This is neither here nor there. Scala has "package objects" and functions put into a package object are scoped directly at the top level of the package. They are not nested within any other object. The only downside to this that I can see, is that at the moment, a package can only have a single package object, which means all the top-level functions for the package have to reside within a single file.
Technically Scala does support top-level functions, because a top level singleton object can extend FunctionX[...]. It just doesn't support the short "def" form of declaring them at the top level.
What do you mean by that? Scala supports closures, currying, immutable data structures, recursion. I'm failing to see how these concepts are less obvious in Scala.
LinkedIn isn't constrained to the JVM, as they had some apps running on CRuby 1.8 and node.js, but they do heavily favor the JVM. JVM interop DOES help with much of their existing codebase which is Java heavy.
Yeah I agree to interoperability. Makes it much simpler to have the same Java stack across the distribution. Either way, that's a big boost to Play framework!
It's been a while, but there was a lot of use of Groovy on Grails a few years ago for exactly this reason. I was a strong advocate of JRuby when we did run Ruby code, but it didn't get very far.
Awesome. I've been using (playing?) with this framework for a bit over a year now and absolutely love it, I'm glad it's catching on as much as it is. The fact that Heroku and the Cedar stack supported has probably helped user adoption a ton.
I'm actually using Play 2.0.x for my first independent venture, which I posted a Show HN about a few hours ago:
I like Play, currently using for a personal project. But ultimately looking forward to the day where frameworks are replaced by mixing and matching libraries where you get just what you need and wire it up exactly how you want to without any limitations.
On the JVM and especially since version 2.1 Play is one of the most lightweight/modular frameworks. At it's core it's just a fast/async http server. So why can't that just be a library you pull in and fire up in a main method?
You can have an IDE or somthing like sbt recompile your changes on the fly so you can get rapid feedback. Ultimately more rapid feedback comes for automated tests vs refreshing your browser and verifying something manually (unless it's UI/lookandfeel changes which are not generally limited by having to compile)
Yup. Play is built on top of Netty and adds value so my point is why not build it as a re-usable library (or set of libs) vs a Framework, it's really not any more difficult.
How do you do DI with Play? It seems as if everything is oriented towards writing static methods:
- controller methods are static
- DB access using the framework seems to involve calling play.db.DB.getDatasource()
- Play's Cache API involves calling Cache.get(), Cache.set()
Are Play applications easy to write unit tests for? Does it involve reconfiguring the framework to use some sort of stub services rather than the real DB/Cache implementation?
Play actually has a really nice plugin system, which we used extensively to integrate Play at LinkedIn. The plugin system offers lightweight support for DI. For example, to use a FooPlugin, you don't use it directly, but ask Play for an instance of it:
What instance you get depends on configuration (typically, a play.plugins file), which makes it easy to swap out implementations at test time. Much of Play's built-in functionality is implemented as a plugin too, including the DB code, so writing unit tests is pretty simple. There is strong support for "fake applications", integration tests, etc: http://www.playframework.com/documentation/2.1.0/ScalaTest
For Play! components, they don't hole you into one DI framework or another. Instead, you can use your favorite DI framework (or with Scala, the cake pattern) on top of any Play API calls.
If you are asking how do you do DI with Play in java, I can't answer your question. If on the other hand you are asking for how to do it in scala, it is quite easy.
Scala's language support for traits, implicit conversions, implicit parameters etc. make dependency injection trivial. Once you get used to it, things like test mocks or IOC containers seem like obvious language smells.
At Pellucid Analytics we're using Play 2.1 with a similar success story to LinkedIn's. The undersold feature IMHO is the asynchronous responses: with the excellent new monadic scala.concurrent.Future interface, you can more easily put together non-blocking web apps with code that looks slick and concise
As a user of your stuff, it doesn't feel like it. It's been a few months, but I always felt the Java documentation and samples were lacking compared to Scala. Then again things may have changed.
Or the logger interface. It's awful. Great that you use the sl4j interface, but I can't cast it to that type because it's a wrapper for the "real" logger written in Scala. It's annoying, and agreed- using Java in the Play framework feels more like a "look what else it can do" than an intentional use-case.
It uses Play's iteratee feature. Also integrates seamlessly with play. My point is that, while the Play team might develop for Java and Scala concurrently, the Play community most definitely is Scala first.
- If initial page load is an issue due to lots of ajax calls, then use server side templating to ONLY insert a single variable which would contain a json object. This way the initial load is fast since the json is templated directly into the page. After load the UI calls rest services to get more data.
I've found that this enforces a clean separation of concerns.
WE have written lot of code in Play 1.2.X all of a sudden they migrated to Play2.0 without any backward compatibility.This is sad.
WIth Play2.0 they introduced Scala Many folks has the opinion that Scala is complex, and i also lost trust in play because of no backward compatibility and i stuck up with huge code base which is not backward compatible
now iam looking build my other new applications on frameworks like Ruby on Rails , django leaving play.
While I don't doubt Play is useful (I haven't personally tried it just yet) I've noticed big tech companies seem to be wasting their time building new frameworks instead of helping improve already existent frameworks in need of new ideas and fresh eyes. Why a new framework? Is it really not a straightforward process to contribute to an already established open source framework for your desired language?
Play is an open source project that has been around for a few years. In fact, that's one of the big selling points for us: we're not inventing something new, but using something the community is using, and contributing back to it.
I've embraced Play! on a few projects, and my experiences have been great. There's no need to expand on existing sentiments, but I will say: this tutorial is excellent. Wish I'd had this when I first got started!
Is it just me, or is Google's Play Store also having a greenish triangle (set at the same exact angle) sort of confusing? I've never heard of the Play Framework, is it related?
Reading people's comments here make me laugh a little bit. ASP.NET MVC been around a few years now and does that and a lot more in a very easy way and in a great platform. I find it really funny how people get commodity software and dress up as the next big thing.
It's pretty much the same as when Microsoft announced nuget after ruby gems and apt-get existed for so long. Why don't they just cut the bull out and call it for what it is?
I've gone from Java frameworks to ASP.NET MVC and back to Java. I really miss ASP.NET. I love the convention-over-configuration in Microsoft's stack. Is your class a controller? Call it SomeClassController and put it in the Controllers folder. That's it. Setting custom routes and doing URL rewriting was a piece of cake too.
I feel that when I try to do anything in Java I always have to consult the documentation which slows me down. The good thing is that there's plenty of it on the Internet but it's still a productivity drag.
I work with ASP.Net MVC primarily (since v1), but I think Play framework have a lot to offer in the JVM web development space.
The biggest key selling point for me is the 'hot' reloading: make changes in your code, refresh your browser, and see the changes immediately. You don't need the whole project to be rebuilt. As far as I am aware, this is what makes Play unique. The 'hot' reloading is probably the reason why it's useful to show nicely formatted errors in the browser (during dev / debug mode), you can see immediately where you stuffed up soon after browser refresh. Errors are also pushed to the console.
However, I realise that ASP.Net MVC View templates can be updated during debugging session, I only wish to be able to do the same with the .Net classes without having to rebuild it.
Plus, being on the JVM you'll have plenty of PaaS deployment options for cloud hosting provider (e.g. Google App Engine, Heroku, OpenShift).
With ASP.NET if you are in a 32 bit machine (who still is?) you have edit and continue so you can do the same as in Play. AFAIK they are working to bring that to 64 bit machines too.
Don't understand me wrong. I see a lot of value in Play. My only beef is with the "this the awesomest thing you'll ever see" approach to selling it.
I have to say I've been wondering for a while what happened to LinkedIn - what used to be a great service has lately taken to a great deal of UI misbehaviour and dysfunction - to the extent that I'm now relucant to go near it for fear of its hangs, jumping menus, and repeated reloads. Perhaps this has been teething trouble switching frameworks?
LinkedIn is a bit scattered when it comes to technology. They also made a big dog and pony show about how the vast majority of their mobile app is built in HTML5, and why that is the best way to do it. A few months later they made a lot of noise about rewriting much of it in native, and why that is the best way to do it. We had an internal debate about whether to use the wrapped web or native, and it was humorous seeing both sides using LinkedIn, and their vigorous arguments, as the foundation of their positions.
For me, the good thing about Play is the platform support. Play 2.X is fully supported on Heroku which makes developers to hack something out really quickly.
LinkedIn uses a service-oriented architecture; the site consists of hundreds of individual services - that is, separate codebases, deployed on separate hardware, built on a handful of different technology stacks. This lets us iterate and scale each service separately depending on its requirements.
We've moved some services to Play already and are now gradually rolling it out for others.
I did enjoy reading this article, though. I'm a novice with Rails, and I have been learning Java for a Coursera course (Algorithms), and the handful of things the article went over seemed straightforward. It would be interesting from my perspective to see different frameworks interacting through a RESTful interface.
>Rapid iteration: change the code, refresh the page, and see the change instantly.
I see the play people tout this all the time, and I assume it is in reaction to an assumption of dynamic language people that you have to manually compile every time you make a change. But it is really misleading. You make a change, refresh the page, and wait 10 seconds for it to compile and reload. Iteration speed was just as poor with play as it was with bloated J2EE monsters on jboss.
I have 8 GB of Ram and SSD and compilation speed hasn't been an issue with me in Play. The refresh process in Play is also a lot better than a JRebel-based solution or something similar, because in case of compilation errors Play generates a nice error page.
The refresh speed may indeed be annoying and could be better, but it's less of an issue with Play than in Rails or Django or whatever, because you're working with a static language and while writing code you feel less of a need to see what your new lines of code produce. In Scala, if you're using it as a functional language, all the code you write tends to be correct if it compiles and Play itself uses many functional idioms making it very suitable for a functional style.
It's worth noting what Play gives you when compared to Rails, Django and the like.
Remember that Rap Genius article from a few days ago, in which people complained about Heroku's Bamboo stack and having to work with over 70 Heroku dynos? I have a Scala module on top of Heroku that's processing 25,000 requests per second in under 100ms per request and that's running with just 8 Heroku dynos. And I'm actually dissatisfied because a high-CPU server on top of EC2 would be able to handle all 25K.
With Play you get the best of both worlds. A productive framework and the full power of the JVM. It's not easy to describe how it feels to get this combination, but it feels great, trust me.
>but it's less of an issue with Play than in Rails or Django or whatever
>It's worth noting what Play gives you when compared to Rails, Django and the like.
Perhaps for some, but we have no interest in dynamic languages or frameworks written in them. We were evaluating frameworks for decent languages only. I was only commenting on the compilation speed issue because they constantly brag about fast iteration when it is no faster than a typical bloated J2EE monster.
Not sure about play!, but with Grails most changes are picked up in < 1 second. Grails 2 is better than Grails 1 about reloading and dealing with domain changes (which by default are hibernate classes) - it used to be that most domain class changes required a restart - not so under Grails 2. I rarely restart my Grails dev env throughout a day - 95% of my changes are as fast as write/save/refresh with PHP.
On my wimpy Macbook Air, most Java changes reload in < 3 seconds. Compared to redeploying an entire Tomcat/Jetty app, this is several orders of magnitude better. Combined with the scala console in sbt for interactive coding, the ~test command in sbt for automatically rerunning tests on each change, and the amazing error handling, this is a massive step forward for Java/Scala web development.
>Compared to redeploying an entire Tomcat/Jetty app, this is several orders of magnitude better.
It is? Are you building a war/ear and copying it to a server to deploy or something? I think every java IDE has support for locally building and deploying within the IDE, which is no slower than play's reloading.
For simple setups, that can work. JRebel can help. For more complex servlet apps, especially those with Spring lifecycle management, this rarely works, which means a full redeploy after almost every Java change.
This is mostly due to the Scala compiler being a bit slow. The team at Typesafe is working on that, but if you don't want to wait just buy a decent recent machine with a SSD and you will get back the snappiness you had with Play 1.
Really? I can see claiming Scala is superior to e.g. Ruby would be controversial, but I can't imagine many people claiming Java is as powerful, particularly here.
Scala has way more language features than Java, that's for sure. It does have powerful abstractions and it makes a lot of things more elegant. You could say the same about C++ compared to C.
But in both cases, sensible people can disagree on whether or not the additional power justifies the additional complexity and those insane compile times.
And just to be a little more specific in what I mean by complexity: What I mean is, how much do you know about what a particular piece of code does when looking at it in isolation? How much additional context do you need to figure out what it does? How many possibilities are there?
Powerful syntactical abstractions are a double edged sword.
It might be surprising but Scala actually has significantly fewer language features than Java. It is also more regular, there are fewer special cases and surprises.
What Scala has done however is to pick particularly powerful features that are allowed to intersect as much as possible giving a lot of flexibility. At the same time it has introduced and encouraged functional programming concepts which are new to many OO programmers with Java backgrounds. This can make it seem a little daunting but I found it no more difficult to learn than any other language and easier than some.
The compile times are simply because the compiler is doing a lot more. It's always going to be slower than the Java compiler, though there are still optimisations that can happen. That's a trade off, the additional expressivity and safety of the type system is either worth it to you or not. In the case of Play, you're getting compile time checked routes and templates for example.
In terms of reasoning, it is much easier to reason about idiomatic Scala code in isolation than it is Java. This is because you have much richer type information and can apply the substitution model without being worried about mutation and side affects. It is true however that the flexibility you are given can be misused and you aren't forced to stick to a functional style, so when someone goes off the reservation that can result in hard to comprehend code. Most of the FOSS projects I've seen in Scala avoid this but YMMV.
I don't doubt that Scala does the things that both languages do in a cleaner, more regular way. But the kind of syntactical abstraction that Scala supports lets you replace semantics that you can't replace in Java, which creates uncertainty. Consider this:
a = b
In Java or C this can only mean one thing. The value of variable b is assigned to variable a. In Scala it could mean the same thing, or the = operator could be overloaded and b could be a method call. If you need to know which one it is, for instance because you're trying to understand someone elses code, then you have more work to do than in Java.
Not a great example because actually you can't override simple assignment but that aside, I was disputing that Scala had more features. It doesn't. I've acknowledged that the features it does have are more powerful and could be abused.
The fact that operators are methods and can be overridden simplifies things - you no longer need to know and remember operators. They are always methods on the type you are looking at. This is what I mean by more regular and fewer surprises, the footprint is smaller.
So you can use this simpler, more powerful feature to create DSLs. They are compile checked and are "real Scala". The tools autoamtically help you. Of course, DSLs exist in Java but they often involve tools like JTB and JavaCC, extra compilation steps, no compiler assistance for users - I could go on. Which is more complex?
Anyway, I agree you could abuse the more powerful language features to write hard to comprehend code. However if you take a look at Scala code in the wild, you will see that these concerns so far have been largely theoretical and of course you can also write incomprehensible junk in Java or any other language should you wish.
I'd encourage people to try the Coursera Scala course which is running again soon, and see for yourself.
It doesn't matter which operator you choose as an example. It's the same with a == b.
And I don't agree that it's a theoretical problem that only arises with bad code. It's simply a downside that we have to be aware of when we use DSLs, even well designed ones. For some purposes bland code is just better than smart code.
But I do agree that a Scala based DSL is hugely superior compared to any byte code manipulation based Java framework that obscures lanaguage semantics beyond recognition. It's also way easier to reason about Scala code than about Python/Ruby style meta programming.
It's funny that you keep picking blatantly wrong examples.
scala> def ==(a: Any) = false
<console>:7: error: overriding method == in class Any of type (x$1: Any)Boolean;
method == cannot override final member
def ==(a: Any) = false
^
Maybe you should actually use the language for a few minutes before commenting? :-)
Maybe you shouldn't try so hard to deliberately misunderstand what I'm saying. Your nitpicking doesn't change the fact that you can redefine what == does in your own classes.
I hope you do realise that my point isn't even specifically about Scala, but about syntactical abstraction in general.
> It might be surprising but Scala actually has significantly fewer language features than Java. It is also more regular, there are fewer special cases and surprises.
Yes, that's what all the Typesafe employees repeat ad nauseam at conferences and on mailing-lists. Anyone who has spent more than a year coding in that language knows how ridiculous that claim is.
I'll just pick one example: _ has six different meanings depending on where you use it.
It's fine to like a language (I love quite a few myself) but don't drink the kool aid and try to remain objective about the strengths and weaknesses of your tools.
You don't like someone's experience and claim that people who agree are basically paid by Typesafe? Great way to debate.
FYI: I don't work at Typesafe, and I share his experience.
One great thing about Scala is that one can immediately tell whether someone has actually used it by looking at the complaints.
Things like "OMG _!!!", "Null, Nothing, None ... sooooo confusing", "Perl", "C++" give it away immediately.
I wonder why people are not more upfront and honest about not having spent more than 5 minutes with Scala.
It's totally OK, no one can learn everything.
I don't deny that. What adds to complexity more than verbosity, though, is that Java's lack of abstraction facilities leads to the overuse of frameworks, including byte code manipulation and excessive reflection. At that point it can get really obscure.
But you can write straighforward Java, and on average reading someone elses Java code is easier than reading typical C++ code for instance. I don't have experience with reading other people's Scala code but it seems similar to C++.
One of the worse examples I have come across is using BigInteger. You end up with code like this:
BigInteger four = new BigInteger("4");
BigInteger sum = four.add(new BigInteger("2")); // assuming you won't need 2 again so why store a in var
I never wished for the ability to do operator overloading anymore than I do when I have to use BigInteger in java. It just makes math look so unnatural and hard to read. You end up with variables all over the place to do Math on numbers or have to create a bunch of them in the method arguments. Just an utter mess when compared to the similar class in C# that does it with operator overloading.
> Java can also become very complex because of it's simplicity.
Another way to say this is that Java is a lower-level language than many newer languages, consequently it's much more wordy. And it is certainly wordy, to the degree that it's difficult to follow one's own code. And I see you make a similar point.
I wouldn't say that. I think the main difference is that Scala spent its language design budget on more useful things compared to Java. Have a look at C# if you want to see a language with tons of features.
> What I mean is, how much do you know about what a particular piece of code does when looking at it in isolation? How much additional context do you need to figure out what it does? How many possibilities are there?
From experience, that amount of code is considerably smaller than Java because I can be pretty sure that some piece of Scala code usually won't mutate stuff all over the place.
Immutability is not a language feature in Scala as it's not enforced like it is in Haskell, so you don't have any guarantees about what a piece of code doesn't do. Granted, you can make a better guess than in Java where mutability is concerned.
Scala's syntax is flexible enough to let you build DSLs. It makes use of operator overloading, optional braces after method calls, infix methods, etc. All features that Java doesn't have.
Being able to build DSLs is a good thing, but the whole point of DSLs is to hide some of the semantics of the underlying language and let you think in terms of the domain the DSL was built for. So there is clearly a power/complexity/understandability trade-off.
Scala is too different from Java to call it better. Java comes with cheap programmers, some of the best tools in the world, reliability, and speed. Scala comes with style (functional, lack of boilerplate, sugar like xml(?)), anecdotal rapid development, and some pretty good concurrency.
Personally I think the syntax in scala is even uglier than Java's, if such a feat were possible, and looking at scala code makes me want to stab my eyes out with forks. Thankfully I don't think I'll have to touch the JVM any time soon.
I would not call Java's syntax "ugly". It is extremely regular and easy to grasp. What it is, however, is extremely verbose. On the other hand, Scala suffers from a bad case of Perlositis: why have one syntax for a language element when you can have three?
It's always about context: if an A/B test show you that changing a button's color from red to blue increases conversion rates by 50%, than red really is superior to blue for this context. Same, if your developers are 50% more productive in Scala than in Java that Scala is a better language for you, same way that red really is superior to blue in the above.
And I really like the dream of a "language agnostic-framework", though I know it's not really possible. It would be cool to have a Play framework which also supports Clojure or JPython or JRuby, as for some developer teams these languages might be superior to Java or Scala - but I know that the development effort would be huge*. But in the real world, 90% of good programmers will take Scala over Java anytime, even if they'll have to learn it! Heck, I'd take C# on mono over Java any day!
I really can't imagine how that is supposed to be even remotely controversial. That's probably as controversial as saying that a $200-CPU built in 2013 is faster than a CPU in 1993.
Isn't that just repeating the “all languages are equal”-myth?
I just hate it when people are right but choose a completely wrong analogy to explain their point: a language's superiority is always context dependent, while a CPUs speed is a cold hard scientific fact (with some gotchas, but nevertheless...). You're right and at the same time using such a wrong argument that you end up feeding the trolls in the process :)
There are certainly languages which are comparatively close, so that it is hard to tell, and where different weightings can lead to different results. That doesn't mean it is like this for every comparison.
For instance, the comparison between Java and Scala certainly doesn't belong to this group, just like comparing PHP with many other languages also leads to a clear outcome.
But honestly, I don't care. There are also people claiming that there is no "objective superiority" in cases like "evolution vs. intelligent design", "6000yo universe vs. billions of years", "software patents vs. no software patents", "no contraception/abortion vs. women's rights".
Its not controversial. Since "superior" is a superlative, it doesn't actually mean anything. So what you said is true but meaningless. Its just a matter of English, not ideology.
My point is that the language is conceited and vacuous, basically used to incite arguments and nothing more. I'm not going to agree or disagree with something that has no meaning.
I wish they had gone with Groovy. Groovy 2.x offers pretty much all the benefits of static compilation and dynamic language features together, it compiles on the fly instantly (being at its heart a dynamic language), and has meta programming features (intercepting it's own compilation and changing the AST, etc.) that would rival Scala's.
There's a project out there somewhere for integrating Groovy with Play but it looks quite immature.
Play 2 stripped out all the Groovy code from Play 1. There must be a reason.
> Groovy 2.x offers pretty much all the benefits of static compilation and dynamic language features together
Groovy's dynamic compilation is reliable, but sloooooooooow. The static compilation added in Groovy 2 is much faster but still buggy e.g. http://stackoverflow.com/questions/14774709/groovy-2-1-0-wei... It was written by one developer, and first shipped in Grails only 2 months ago. And does Grails actually use any of Groovy's static compilation features? I haven't seen anywhere it's used: point me to somewhere in the Grails codebase if it does.
You don't get all the benefits of static compilation and dynamic compilation together, you can get bugfree (but sloooooooooow) code, or faster (but buggy) code.
> Groovy's dynamic compilation is reliable, but sloooooooooow.
I guess you mean execution speed, not compilation? Compilation is fast enough I think. Execution certainly compares fine with other dynamic languages, at least, in my usage (and for some things it is much faster).
> The static compilation added in Groovy 2 is much faster but still buggy
The bug you mention is certainly bad, but it was addressed extremely quickly. Are there other examples?
> It was written by one developer, and first shipped in Grails only 2 months ago
A little misleading - static compilation has been in core Groovy for 9 months or so and is now supported by the core groovy team.
> And does Grails actually use any of Groovy's static compilation features?
I don't know, but it's not really relevant. I'm not advocating for Grails here, I'm advocating use of Groovy with Play. Part of the reason I want that is that I'm not extremely fond of Grails for various reasons.
When Groovy's author said he prefers Scala (http://macstrac.blogspot.ro/2009/04/scala-as-long-term-repla...) it pretty much sealed the language's fate... though, in all seriousness, there really is too much language diversity on the JVM (how tf would one choose between Groovy, JRuby or JPython? - yeah, you choose the framework not the language, but still, it means that all the good developers are split working on different projects).
That statement is misleading. James Strachan left Groovy a long time ago. Guillaume Laforge has lead the project from almost death to one of the most popular languages in use today.
Most of the technical work has been done by Jochen Theodorou. Others who have helped technically are Paul King, Cedric Champeau, Alex Tkachman, and Jeremy Rayner. James Strachan also did a lot of technical work on Groovy in his day. I'd rather listen to what someone who's done technical work has to say than someone who shows powerpoint slides.
You mentioned Guillaume Laforge as leading the Groovy project, but from my experience, Graeme Rocher, the Grails Project Manager, seems to have far more say over Groovy's direction.
As for calling Groovy "one of the most popular languages in use today", it figures fairly low in most popularity ratings (e.g. not in Tiobe's top 50), and only shows the occasional burst when it's been actively talked up, e.g. just before a conference when the project managers are selling conference seats.
That piece is very dated, and your comment is misleading. He didn't consider Groovy as a replacement for Java at the time because it was not statically typed and did not compile to fast byte code.
In fact, if you read through all the reasons he recommends Scala, every one of them has been addressed in Groovy in the last few years.
Scala did it all first, and has been battle-tested over many years, while Grbdvy's only recently added static compilation. JRuby did invoke-dynamic before Grbdvy, and Clojure did concurrency before Grbdvy's GPars.
...the thing that put me off was the lack of a real ORM for Go (it's on their wishlist but nobody's working on it). I know, I know, "ORMs are all wrong and evil", but when it comes to boring web cruds I'm an ORM whore.
ORM's can be a timesaver, but there are advantages to not envisioning your sql tables as objects, and envisioning them as tables.
One thing that comes to mind is ACID compliance. Any other pluses of using sql over an ORM would be appreciated. I have a friend who swears by it, who taught another friend that is now swearing by it.
I was going to say the same thing, but I'll just second you.
When you use "sbt ~run", sbt compiles each file as soon as it changes. I.e., as soon as you save out the editor buffer. By the time you click on the reload button, sbt has usually already compiled all your changes, and it only takes a second or two for either your working page to reload, or for you to see a compiler error message.
I agree with eloisant, if you get a decent machine with an SSD, Play is quite snappy. Recompilations are around 1 second on my MacBook Pro with retina display, which is a small price to pay for the type safety you get with Scala
We ended up using Haskell, which is also famously slow at compiling. But it has been significantly faster than play thus far (using snap's development mode).
You should run Play with "~run" which recompiles on file-change. Running with just "run" doesn't recompile until you hit refresh in your browser. This provides a noticeable difference in the "effective" compile time.
We did. The difference is negligable, it takes a fraction of a second to hit f5. In fact, it costs time fairly often as you save the file, notice right away that you have a typo, fix it and save again, but now it is still busy compiling from the first time so you have to wait out two compiles.
It's a bit sad to have to look outside the standard stack for good solutions to this, but I've had great results with JRebel. The rapid iteration it brings to java easily pays for itself almost immediately, if nothing else than in not having to pull your hair waiting for classloader reloads...
I used Play in a startup backend and I won't be able to say I was satisfied with it. Play v2 is especially slower on your local development box, compilation takes some time and I actually still like Play 1.2.x family more. Its memory consumption was horrible on production (I made really a lot jvm adjustments and could not get it properly).
Personally, I now like Python frameworks (e.g Flask) and they are much easier, but I am not sure if you should rely your whole service infrastructure or enterprise software on a dynamically typed language stack. There are companies out there achieved this but I think Java or Scala will be just fine for LinkedIn, and by the way why the hack they don't allow comments on their engineering blog?