Tuesday, October 16, 2007

Fun With Scala: Things I'm Learning From Lift #1

So I'm starting somewhere around the very beginning with the Liftweb framework: LiftServlet.scala, which is in the net.liftweb.http package. This looks like Lift's answer to a Rails controller, or a Struts Action (Author's Note: probably with some caveats that I haven't found yet; (pleasant) comments welcome if I'm wrong about this).

Fun Thing #1: The very first import is
import javax.servlet.http.{HttpServlet, HttpServletRequest , 
HttpServletResponse, HttpSession}

How's that for interoperability with Java? I haven't gotten that far yet, but this tells me that whatever Lift uses for its request/response implementation is going to conform to the usual Java interfaces. And how do you like the syntax for this style of import? I like it a lot, because it lets you do the equivalent of:
import javax.servlet.http.HttpServlet
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse
...et cetera...

...on a single line (it's a single line in the original source; I've split it here for friendlier rendering). Without resorting to importing everything in the http package with a wildcard. This way you get to see exactly what you need. Yeah, I know a good Java IDE will manage the imports for you, so it's not as much of a pain as it used to be, but I like the compactness of this syntax. As it happens, the current version of the Scala plugin for Eclipse doesn't have the equivalent of "Organize Imports", so this syntax is definitely a boon.

Fun Thing #2: There's a syntax for importing not just classes, but members of a class. Like so:
import net.liftweb.util.Helpers._

This basically says "make everything in the Helpers class (actually it's a singleton object, but think of it as a class for now) available to this class without my having to qualify it with 'Helpers.' all the time".

For example, there's a bit of code in LiftServlet that goes like this:
val md = parseInternetDate(mod)

This makes it appear that parseInternetDate() is defined in the LiftServlet class. But it's not. It's defined in Helpers. If you're used to modules/mixins in Ruby, this should seem very familiar to you. If not, now might be a good time to get used to them, because they're way cool.

Fun Thing #3: No, the lack of semicolons at the end of the code samples is not a typo. The Semicolon is Dead! Long Live the Semicolon! No, scratch that -- Long Live Scala!