Search

What the Quote?

"You're not talking about the software, right? You're talking about the disease?"

David Bradshaw

"You can't light cigarettes with chapstick... I've tried, it doesn't work."

Pete Oberlin

"Ya got a problem with me? Talk to my tiger."

Laura Hearron

« VGltIFRyaXBjb255 | Main| I'm a speedgeek »

I have a man-crush on server-side JavaScript

Category xpages
Long-time readers of this blog are familiar with my rants about what I perceive to be the shortcomings of various programming languages - the lack of method overloading in LotusScript, the bulkiness of Java's structure and syntax, and so forth - but in server-side JavaScript (specifically, IBM's implementation thereof within XPages), I've finally "fallen in love" with a programming language. Although I've only been tinkering with it for a couple months, I've already found that it addresses nearly every pet peeve I've had with each of the languages that it effectively absorbs, while retaining the strengths I cling to from each of them. Here are just a few of the highlights I've discovered thus far:
  • Global variables that make sense: you don't have to declare and instantiate a variable for the current session and database; you can immediately refer to each with that name (i.e. session.getDatabase(..., database.getView(...). Naturally, if you want a named handle on any other database, you'll need a separate variable for it. But "database" is already bound to the current, so you don't have to "Dim" (or even "var") it... you've already got it.
  • Local variables bound to a control context: in a repeat control, for instance, the two most important attributes (in the source XML.. they also show up on the properties pane) are the "value" and the "var". The former defines the collection the control will iterate (the most obvious example is a view panel, but you can define custom collections... an array of JavaScript objects, for instance); the latter is the variable you want bound to each member of the collection. On a view panel, then, if you set "var" equal to "thisViewEntry", from anywhere inside the repeat control you can do stuff like "thisViewEntry.getDocument().getItemValue('Subject')". In other words, you don't have to do the usual array index maintenance... the named variable is simply bound to the current collection member.
  • Painless construction of complex objects: none of this "HashMap<String,Widget> hoozit = new HashMap<String,Widget>()" nonsense... you can use the object literal syntax to make your objects as simple or complex as you want and then cram the whole result into a single variable:
    var whatever = {
    name: 'something',
    friends: [ ], // he doesn't get out much
    size: 7,
    nestedObject: {
    greeting: 'hello',
    greet: function(newFriend) { alert(greeting + ' ' + newFriend.name); }
    },
    myProfile: database.getProfileDocument('userProfile', session.getEffectiveUserName())
    }

    All of that gets interpreted into some Java hierarchy that we don't have to grok... we just create our object fluidly and let Rhino do all the hard work.
  • Closures: I was rather surprised by this one. SSJS actually supports closures. If you don't know what closures are, learn. Seriously. More power, less code. Closures are a very good thing.
  • Scope maps: JSF (the basis for the XPages engine) provides access to three handy globals: requestScope, sessionScope, and applicationScope. Each is stored as some kind of Map (probably a HashMap), but each has a different purpose. Bottom up, requestScope exists only for the life of a single HTTP request, sessionScope is per user, applicationScope is per NSF. In other words, everything you used to write to disk somewhere (cookies, profile document, etc.) to reference across multiple page views (or even within the same transaction) can now be tucked neatly away into the server's RAM for convenient access later on. For example, here's a generic function for returning a database setting once per server reboot:
    var getApplicationSetting = function(settingName) {
    var scopeKey = 'databaseSetting-' + settingName;
    if (!(applicationScope.containsKey(scopeKey))) {
    applicationScope.put(scopeKey, database.getProfileDocument('databaseSettings')
    .getItemValueString(settingName));
    }
    return applicationScope.get(scopeKey);
    }

    This is where you really get some performance gains. Sure, getting a handle on a profile doc is quick, but imagine all the fun things you can drop into this space and retrieve by name without the expense of querying the database at all. One catch: if you want to cache actual Domino object handles (database, view, document, etc.), don't put them in the session or application scope... they'll get recycled between requests. This includes objects that have Domino objects as members; the container object will survive, but its Domino object members will get recycled. So it's fine to drop a document handle into the requestScope at the top of an XPage and then reference it later on... in fact, that's precisely what requestScope is there for (as opposed to having to obtain a fresh handle for each control). Just don't put it in requestScope or sessionScope, or your server log will rapidly fill up with lots of yucky stack traces.
And those are just the few items I can think of off the top of my head. See why I'm swooning?

Comments

Gravatar Image1 - Yeah, very swoonable. Couple things: Last I checked, it wasn't Rhino. IBM rolled their own JS engine for the JVM in Workplace, mostly, I understand, due to IP issues. Since Rhino ships with Java 6 as the reference language for JSR 223 they could have switched for 8.5. I'd be a little curious how they would maintain the @function naming if that were the case.

I would LOVE for it to be Rhino. I would probably even swoon.

Gravatar Image2 - That wouldn't surprise me; they do have a long history of duplicating others' functionality in their own implementation primarily so that they can have control over any changes to it (for instance, maintaining an entire duplicate JVM and, thus, typically stuck two versions behind the rest of the Java world, which is why I was delighted when I heard 8.5 would finally bring us current with Java 6). I had seen the Rhino JAR somewhere within the Notes folder structure after installing one of the public betas of 8.5, but now that I'm running the gold release it seems to have disappeared......

Gravatar Image3 - Easy creation of complex objects, FTW!

Post A Comment

:-D:-o:-p:-x:-(:-):-\:angry::cool::cry::emb::grin::huh::laugh::lips::rolleyes:;-)

Contact Me

Elsewhere

Assorted Linkage


Locations of visitors to this page