Thursday, March 12, 2009

JavaScript needs Elvis

I submitted an enhancement request to the Mozilla folks yesterday. My request? Add an Elvis operator to JavaScript.

If you program in Groovy, you already know what I'm talking about, and it has nothing to do with impersonators or Las Vegas.

If you're not familiar with the Elvis operator, here's the text of my enhancement request to Mozilla:
An Elvis operator similar to Groovy's (which is also being considered for
Scala, and is in the vein of C#'s null-coalescence operator) would add
significant value to JavaScript by letting coders write safer scripts with very
little added effort.

Please see for a

Basically, Elvis is a collapsed version of the Java/C ternary operator:

return user ?: "Anonymous"; // if user is null, use "Anonymous"

(Allows a function that's supposed to return a String to always return a String
and never return undefined or null.)

function cat(b,c) { return (b?:"") + (c?:"") ; }

Calling cat() with zero or one args still produces a safe return value; caller
needn't check for null or undefined; function needn't contain arg-sanity

In short, the availability of an Elvis operator makes sanity-injection easy and
will improve the robustness of scripts in the wild as people start to use it.
Alas, Brendan Eich summarily dismissed my suggestion, saying that "idiomatic JS already uses || for the same purposes, but admitting other 'falsy' values than null and undefined."

Eich offered the following illustration:

function cat(b,c) { return (b || "") + (c || ""); }

To which I say: Yes, of course, that sort of kludgy thing works and people use it all the time. But is it right?

While I can appreciate Eich not wanting to "junk up" JavaScript with new operators, I think using the logical-OR operator in the foregoing hacky way does nothing to make code more readable or preserve ||'s original semantics, IMHO. That's the whole point of having a separate operator. The semantics are unambiguous (to a human being, which is what counts; never mind the interpreter).

I'm not alone in this opinion. See Scala Elvis discussion. See also the discussion of null convenience operators for the Fan OO language. See also Stephen Colebourne's excellent discussion of a proposed Elvis syntax for null handling in Java. See also the C# null-coaslescence operator.

I respect Brendan Eich more than apple pie itself, but I think it's significant that others have already considered his argument and found it wanting.

There's still much to recommend Elvis. Java could certainly benefit from it. How many lines of sanity-checking code have people written at the start of a method to to see if arguments are null? More important: How many lines of such code have not been written (through sheer oversight), resulting in mayhem later? (Let he who is without sin throw the first NullPointerException.)

While we're at it, I think Java could use a safe property accessor (a la Groovy):

theName = user?.name; // gives null, not NPE, if name is null

Colebourne has published data (acquired at Devoxx) showing that better null handling is the No. 1 most requested feature by Java programmers. The actual whiteboard photo from the data-gathering session is here (warning: large image).

When programmers beg for a simple syntax feature that makes the language safer and easier to read (while eliminating tedious sanity-checking boilerplate), why not put the feature into the language? What justification could there be for not doing so? Who benefits by keeping a feature out of the language that would cut down on null pointer exceptions?

Does JavaScript (and Java) need Elvis? I'm convinced it does. What do you think?

Thank you . . . Thank you very much.


  1. Hm. I am on the fence about this.

    Part of the reason I prefer using || is that it's not a logical-OR operator in my mind. It's a shortcut-boolean-OR. In other words, it keeps evaluating operands until one is not falsy. My impression has been that this was the original meaning of this operator from the beginning, but the documentation never reflected this (since it was written by Java / C devs?).

    There's a similar argument for the shortcut-boolean-AND operator, too.

    theName = user &&; // returns null or undefined if user is null or undefined

    This is the Javascript way: concise and fast at the risk of being ambiguous at times.

    On the other hand, these new operators are so simple and even more concise under certain circumstances. Hm......

  2. Anonymous2:16 PM

    @unscriptable: C and Java have short-circuiting || and && -- C always has, so all C-derived languages that I know of do to.

    The statement "... I think using the logical-OR operator in the foregoing hacky way does nothing to make code more readable or preserve ||'s original semantics" shows a lack of familiarity with not only short-circuiting in the original semantics of JS, but more to the point, of the value-preserving nature, inspired by Perl and various Lisp dialects of JS || and &&.

    In JS, e1 || e2 not only evaluates only e1 if it is truthy -- the result is the value of e1, not true. If e1 is falsy, then the result is the value of e2, not the result of converting e2 to a boolean value. Similarly for &&.

    This was standardized 12 years ago in ECMA-262 (ES1). It is used idiomatically all over the web, which is why I argue (not dismissively, or I would not have written a comment in that bug) that it is fruitless to add another operator -- so long as the looseness of JS's truthy and falsy judgments is considered good.

    If we need a more precise test than "converts to true" or "converts to false" to decide short-circuiting (but not of course result value), then there could be room for a ?? or ?: operator.

    If you read the list archives, you will find multiple threads on this question, citing C#'s ?? operator and Ruby's || and ||= operators (Ruby || is similar to JS || but not the same). For ES4 we considered ||= and &&=, decided the latter was useless, but kept the former as short-hand for the very common JS idiom:

    function foo(bar) { bar = bar || default; ... }

    Arguing about other languages, which may or may not have JS's || and && Perl-inspired value preserving semantics, is not productive. Arguing about hackyness is flame-bait. JS has its own idioms, as does any language. Trying to crowbar another operator in because Groovy (or brand-X) does it won't work.


  3. One more point. Filing a bugzilla bug:

    that asks for a new operator to be added to Mozilla's SpiderMonkey JS engine is, as I said in my comment #1 in that bug, barking up the wrong tree.

    We extend JS from the last ECMA-262 standard in Mozilla's implementations, but we always try to do so based on public proposals that have been aired on, specified informally in the wiki, and thus made known to Ecma TC39 members.

    I suggest catching up on the ||= threads in es-discuss, then posting there, if you are interested in pushing ?: or anything like it. But again I don't think the case for ?: is grounded in the particular semantics of JS, or knowledge of what has come before "Elvis". It needs to be.


  4. I have to agree with Brandon as well. If you find (c || "") ambiguous, then you don't understand how || and && work in JavaScript.

  5. Anonymous5:19 PM

    See also this article from Oliver Steele:

    His main point is that this is really a form of the "Maybe" monad, but along the way he gives some interesting JavaScript code, including the "safe property acessor" pattern:

    theName = (user||{}).name; // undefined if user is null


Add a comment. Registration required because trolls.