Infrequently Noted

Alex Russell on browsers, standards, and the process of progress.

On JS "Lambdas"

The ES working group is hard at work on "Harmony", the goals of which are significantly more sane than previous attempts to build a new language from JavaScript. Namely, they're being careful to be able to express things in new syntax based on old syntax. This is referred to as "de-sugaring". Many new bits of syntax will be expressed in old syntax in a resulting spec, and so it will be with any new lambda syntax.

One of the things I find most persistently annoying about the language as we have it is the verbose and wordy way of saying "build me a new invokable thing". Since JS builds dynamic scopes based on on functions, this is particularly annoying when writing event handlers, callbacks, and arguments to forEach and friends. Needless to say, these are the things we do all the time in JavaScript. If there was anything that deserved syntactic sugar, this is it.

This brings us to "lambdas". Languages like Ruby have a great syntax for expressing "a thing you can invoke" in a terse way. Python has something along these lines based on the keyword lambda, but Guido insists on keeping them neutered based on (AFAICT from in-person discussions) a dislike of functional programming. Java is dangerously close to getting useful closures but it's so syntactically handicapped that it'll probably be another decade before the masses rebel and demand a terse way to say what they mean. Or maybe they'll all have just defected to JRuby. For most of these languages, being able to say "here's a new invokable thing" tersely is a Nice To Have feature. No real-world program will be slowed down by the size of a keyword. Indeed, Java makes you do so much work for the compiler that it's practically taken as a badge of honor that you have to type it all out over and over and over.

JavaScript is different. Unlike nearly every other language, the terseness of JavaScript code is a key determinant in the performance of a web application. The bigger your scripts, the slower your app loads. It's as simple as that.

It's a crime, then, that we still have to type:

node.addEventListener("click", function(evt){ /* ... */ }, false);

// or

[/* ... /].forEach(function(i){ / ... */ });

The syntax for "an anonymous invokable thing" should be a lot shorter given how much exercise it gets in the real world. What real-world script authors don't need is something other than "a shorter way to say function". Anything different than this isn't strictly useful. Anything that requires you to use a more wordy syntax to name arguments is a failure, and anything that uses a name longer than the shortest possible thing just re-introduces that bug that needs fixing in the first place. There have been proposals at the ES working group to date regarding "lambdas" and most assume that they will be something that serves to make implementer's roles easier when it comes to de-sugaring but fail in one of these ways. Folks who write actual scripts should start speaking up and telling the Harmony working group what needs to be clearly and un-ambiguiously said:

Don't fuck with the semantics of function, just let me stop typing it so often

What might a better syntax for function look like?

The best that Erik and I could come up with that is relatively unambiguious for parsers, doesn't introduce hard-to-type characters on certain keyboard layouts, and doesn't mess with the semantics of function(){} is this:

// empty function body, zero arguments
var lambda = #(){ /*... */ };

// empty function body, arguments list elided away var lambda = #{ /* ... */ };

// we can re-write the previous examples as: node.addEventListener("click", #(evt){ /* ... */ }, false);

// and

[/* ... /].forEach(#(i){ / ... */ });

The long history of the word "lambda" coupled with the different interpretations that various languages place on them make using the word "lambda" to say "a short name for something you can invoke" particularly loaded. Perhaps instead we should just call this new syntax that crams a lot of meaning into a short "keyword" something else entirely.

"Cramdas", anyone?

Update: ...and James Padolsey makes it so!.

Dojo Wins Mobile Slickspeed Shootout

Stefan K. has posted a fascinating run-down of mobile browser performance with regards to JavaScript toolkits. No big shock, but Dojo once again brings home the bacon. I'd love to see these tests re-run with TaskSpeed instead of SlickSpeed, but when you're doing progressive enhancement it turns out that selector engine performance really matters. Dojo continues to do very well in both TaskSpeed and SlickSpeed because the Acme selector engine is so darned fast. In the real world, selector speed matters and the faster it gets, the more queries we seem to do.

I'm not entirely sold that the right solution going forward is to use the toolkits we already have, but if you're building a mobile app today and you're going to use a toolkit, it looks like (as on desktop browsers), Dojo should be your first choice. The webkitMobile variant of Dojo points to one possible way out of the "what to do about mobile?" conundrum regarding size and IE-induced bloat, but I have some hope that WebKit will improve quickly enough to make the toolkits of today obsolete on mobile phones entirely. Time will tell.

Hat tip: the Uxebu blog

Older Posts

Newer Posts