Ikai Lan says

I say things!

First impressions of Lift Scala web development framework from a Ruby on Rails developer

with 8 comments

Over the past few months I’ve been hearing a lot about Scala and, in general, very interested. Scala, short for “scalable language” (and why I will continue to pronounce it “skay-lah” rather than “skah-lah”) is a strongly typed JVM language that combines aspects of functional programming and dynamic languages with static typing and the JVM to provide a language that has some of the flexibility of languages such as Ruby or Haskell, but with the performance and interoperability of Java.

One of the projects leading the charge in Scala is Lift, a web development framework. I’ve been developing in Ruby on Rails for the past few years, and really, I don’t need to learn another framework. I took a very close examination at Django and even built a few projects, but stuck with Rails as my primary tool of choice. Lift interests me for the following reasons:

  • can run in any Java Application Server
  • can run inline Java

Why are these important? I’ve met a lot of consultants who will recommend a solution for a client that requires a deployment mod_php/Erlang/WSGI/Mongrel and got the project shot down. But switch the pitch to Java running in an application server? Happy client. I’ve been pushing JRuby hard on every other Rails developer I meet, so these requirements are not high on my list, though they add a lot of points. Also – it should be worth mentioning that many, many Java based frameworks such as Grails or the recently open sourced AribaWeb can do these.

  • high performance* (have not seen with my own eyes)
  • uses Scala
  • out of the box Comet support

Comet is a way of simulating push applications over HTTP using a browser, which is completely a client pull type of application. Comet is also known as long polling, and it is how every single JavaScript browser chat application works (Meebo, Facebook chat, etc). Basically, the client JavaScript opens an XMLHttpRequest (XHR for short) to the server which the server does not respond to until there is data to be pushed (hence the name “long polling”). This gets rid of the need for clients to poll the server at intervals which has two problems: at longer intervals, data is not pushed as quickly, which would make an IM application unusable. At shorter intervals, browsers would quickly saturate their network connection as well as the server. Comet isn’t without its problems. Most Java applications, for instance, use a “one thread per request” model for each open connection, which does not scale efficiently as the threads would be the limiting factor in the number of clients that could connect at once even though most of the time the threads would be idle. In fact, open connections was such a problem that Facebook’s chat implementation is completely written in Erlang, a concurrent language that can create millions of lightweight processes and was really the only implementation that could scale efficiently to their needs. They blog about it here: http://www.facebook.com/note.php?note_id=14218138919

The way Lift deals with Comet scaling issues is by making use of Jetty Continuations. The thread-per-request model is still used, however, threads are suspended when they are not needed, resulting in a much more efficient use of resources.

It’s these reasons that make Lift appealing to me to learn. However, after fiddling with Lift, there are a few things off the top of my head that I already don’t like much about Lift or are so different they threaten to make my brain reboot:

  • Servers are not stateless. If you need to horizontally scale, your load balancer needs to read the JSESSIONID parameter in the HTTP request and direct traffic based on that information. I’ve been told that Lift is so incredibly high performance this isn’t necessary. This doesn’t answer the question of hot failover, and frankly, I was a bit disappointed.
  • Everything depends on state! This is probably WHY Lift can be so high performance. Most web frameworks deal with requests as they come in, looking up the same data per request to reinstantiate session objects, User objects, or any other objects that need to persist longer than a web request. It’s a completely different way of thinking about problems and web development that experienced web developers coming into Lift from other frameworks will have to come in with a blank slate. Lift encourages abstracting away the request/response cycle. It remains to be seen whether this is a good thing or a bad thing.
  • Unintuitive way to add new pages. You have to add to a sitemap in what might be the most unintuitive manner possible:
    val entries = Menu(Loc("Home", List("index"), "Home")) :: Menu(Loc("Test", List("test"), "Test")) :: User.sitemap

    The :: is the operator for list concatenation. This will make all your pages appear in the site menu. To make pages that don’t appear in the site menu?

    Menu(Loc("MyHiddenPage", List("hidden"), "hidden", Hidden))

    To me this seems unintuitive, but then again, I don’t actually understand what is happening here, as the API docs are unusable. I haven’t figured out routing yet, for instance. When I was learning Django, I figured out how to set up routes to functions in minutes.

  • Scala shorthand. I’ve mentioned this and all the functional programmers have screamed bloody murder. Code is for human beings, not cyborgs. I understand that it’s clever to save keystrokes:
    list.sort(_ < _)

    As opposed to, say, Ruby:

    list.sort { |a, b| a < b }

    But these are trivial examples. There’s code all over the place that looks like this:

    fun1(a, b _).call(_).fun2(_ <= _)

    I’m sorry, but that’s not very welcoming. The worst part is that Scala HAS verbose syntax. You can use underscore notation, or you can use:

    () => something
     (x) => x.something

    I was at a job interview once where I was asked to write code to solve a problem using any language I wanted. I wrote a monstrous Ruby one-liner that was fun to write but that I would never, ever write in real life if I expected other developers to read my code. Sometimes there really is such a thing as too clever.

  • Dearth of working tutorials or documentation* (I plan on writing tutorials for as long as I am learning or interested in Lift)

In spite of these things I still think Lift has an interesting approach to many of the problems of web development. Rather than judge Lift based on my initial impressions, I’ll get into it some more before I decide if it’s a technology that I’d push. Ruby On Rails was one such technology, and in spite of all of its problems I still view it as an amazing development platform. The difference here is that by the time I started learning, several books had already been written, and there were plenty of tutorials on the web.

One of the problems with Lift is that most of the tutorials I have seen so far are written by actual developers of Lift. As a developer, it’s hard to figure out what people need to know. There’s a tendency to say to new developers coming on, “You only need to know A, B and C.” Then, thirty minutes later, when the new guy is completely lost, “Oh, and D! Sorry!” As a newbie, trust me, I won’t miss D. It’ll be in my face such that I’ll get mad, stop coding, then complain on Twitter, on the mailing list and in this blog.

As for the immediate future, I’ll continue writing tutorials for Lift, beginning with a tutorial coming soon about how to get started developing on Lift with NetBeans. Stay tuned.

Advertisements

Written by Ikai Lan

March 3, 2009 at 8:39 pm

Posted in Lift, Scala

Tagged with ,

8 Responses

Subscribe to comments with RSS.

  1. Ikai,

    Perhaps the lack of documentation has colored your perspective on SiteMap (the whole Menu, Loc thing).

    SiteMap is optional, so you can remove it from your code and manually manage access control to pages and generation of menus and bread-crumbs.

    I wrote SiteMap (first for Java https://www.lostlake.org/sitemap.wmv , then for Ruby http://rubyforge.org/projects/sitemap/, now for Lift) because almost every site I ever worked on had dynamic menus and page-level access control rules.

    SiteMap encapsulates the following features:
    – Dynamic page level access control You define the access control rules as part of the Loc[action] and it can include current state (is the user logged in or not, is the user a super-user) as well as testing to make sure that the request has certain parameters and that the parameters are valid
    – Hierarchical (nested) menu support. So you can have sections, subsections, sub-sub sections, etc.
    – Page aware menu display. Only the pages that you’re allowed to access will be displayed. For nested menus, you’re shown menus at the levels above you, at the current level, and the menus in the nest just below you (see http://demo.liftweb.net/menu/two )
    – Breadcrumbs… the menu nesting that got you to your current page
    – URL rewrite and parameter extraction. This is like routes in other systems, but with SiteMap, the parameter extraction is type-safe and is bi-directional so that you can construct URLs from type-safe data, also using SiteMap. Note that you can do the URL rewriting (routing) separately using a lighter weight pattern matching syntax as well… which also reinforces that SiteMap is optional.
    – Page title generation
    – A few other things that escape me right now. :-)

    The “dpp practice” (I won’t call it best practice because my conventions are not always best) is to put Menu/Loc definitions into a domain object singleton and assemble the menus in Boot.scala. You can see this with User.menus. And, if you don’t like Scala’s :: for List item concatenation, there are other ways to build Lists.

    Thanks,

    David

    David Pollak

    March 4, 2009 at 6:22 am

  2. Ikai, I look forward to the series – it’s a great idea. On the plus side, it looks like at least one Lift book is close to publication:

    http://www.apress.com/book/view/1430224215

    Rich Apodaca

    April 3, 2009 at 8:19 am

  3. I’d hire you in a minute, Aaron Carlino, if I could come up with the money and had the authority. If our college ever loses its current Webmaster or Graphic Arts Specialist, I feel you would be able to do both jobs….amazing talent and time manager. Now, don’t forget about the life balance factor…..enjoy!

    Jacklee

    June 1, 2009 at 3:36 am

  4. Thanks for this write-up. I’m curious, have any of your positions changed since your initial post?

    I’m debating about sticking to Groovy & Stripes for a midtier webapplication, or maybe giving Lift a go.

    You’re bullet point on “everything relies on state” worries me a bit.

    rickcr

    June 26, 2009 at 6:00 pm

  5. Came across this website after getting frustrated with the Lift framework. I couldn’t agree more with what you have written.

    I tried Lift after looking at Apache Click, Apache Wicket, Sprite and a few other frameworks. Lift is, by far, the most (needlessly) complicated framework I have come across.

    Perhaps I am stupid, but I had a very difficult time with the documentation.

    Lift has such promise – scala is so much faster than Ruby, Groovy etc.. and Lift should have become a dominant framework now (more so that Grails, Rails etc). But the needless complexity due to the fact that the developers have chosen to NOT emphasise simplicity over “cleverness” has resulted in Lift finding very few takers as compared to (G)rails.

    I especially liked the line “Sometimes there really is such a thing as too clever.” So true.

    Philip

    November 20, 2009 at 6:30 am

  6. Ikai, Looking forward to your next series in lift.

    Regards,

    Teena

    Teena George

    December 21, 2009 at 8:58 am

  7. My first impression coming from Spring MVC, Grails and Rails is this: Lift is a mess. I don’t think it’s fixable. It may be faster than (G)Rails but speed is not everything.

    Eric P

    April 4, 2010 at 5:43 pm

  8. Ruby on Rails is truly a great framework. Once you have learn the process of it, the work will definitely run smoothly. In line with Ruby on Rails I would like to introduce a Rails middleware that I’m using and it helps me a lot, the Simpleworker.

    Rommel

    January 9, 2011 at 5:08 pm


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s