Vincent Gable’s Blog

October 20, 2009

JavaScript Nailed ||

One thing about JavaScript I really like is that its ||, the Logical Or operator, is really a more general ‘Eval Until True‘ operation. (If you have a better name for this operation, please leave a comment!) It’s the same kind of or operator used in Lisp. And I believe it’s the best choice for a language to use.

In C/C++, a || b is equivalent to,

  if a evaluates to a non-zero value:
    return true;
  if b evaluates to a non-zero value:
    return true;
  otherwise:
    return false;

Note that if a can be converted to true, then b is not evaluated. Importantly, in C/C++ || always returns a bool.

But the JavaScript || returns the value of the first variable that can be converted to true, or the last variable if both variables can’t be interpreted as true,

  if a evaluates to a non-zero value:
    return a;
  otherwise:
    return b;

Concise

JavaScript’s || is some sweet syntactic sugar.

We can write,

return playerName || "Player 1";

instead of,

return playerName ? playerName : "Player 1";

And simplify assert-like code in a perl-esq way,

x || throw "x was unexpectedly null!";

It’s interesting that a more concise definition of || allows more concise code, even though intuitively we’d expect a more complex || to “do more work for us”.

General

Defining || to return values, not true/false, is much more useful for functional programming.

The short-circuit-evaluation is powerful enough to replace if-statements. For example, the familiar factorial function,

function factorial(n){
	if(n == 0) return 1;
	return n*factorial(n-1);
}

can be written in JavaScript using && and || expressions,

function factorial2(n){ return n * (n && factorial2(n-1)) || 1;}

Yes, I know this isn’t the clearest way to write a factorial, and it would still be an expression if it used ?:, but hopefully this gives you a sense of what short-circuiting operations can do.

Unlike ?:, the two-argument || intuitively generalizes to n arguments, equivalent to a1 || a2 || ... || an. This makes it even more useful for dealing with abstractions.

Logical operators that return values, instead of simply booleans, are more expressive and powerful, although at first they may not seem useful — especially coming from a language without them.

3 Comments »

  1. You wrote:
    [[It’s interesting that a more concise definition of || allows more concise code, even though intuitively we’d expect a more complex || to “do more work for us”.]]

    My sense of it is that much of the work done by || is due to its complexity. Particularly, the way it is not a function strikes me as complexity.

    Regardless, I like the way it drives phrasing. I’ll keep this structure in mind. Thanks!

    Comment by Tracy Harms — October 21, 2009 @ 12:43 pm

  2. I am working with the name ‘ifmissing’ for my approximation of this construct in J. A simple tacit implementation, in which the only type of “missingness” that counts is having no atoms, is written as follows:

    ifmissing =: ( 0(e.$)] ) >@{ ] ,&< [

    This has been restructured so that the right-hand argument, not the left, provides the “preferred” value. This is because the evaluation of nouns and verbs in J pipelines values from the right to the left.

    Example use, from a console session:


    default_nm =: given_nm =: ''
    '.doc' ,~ 'afile' ifmissing default_nm ifmissing given_nm
    afile.doc
    given_nm =: 'newnotes'
    '.doc' ,~ 'afile' ifmissing default_nm ifmissing given_nm
    newnotes.doc

    Comment by Tracy Harms — October 22, 2009 @ 1:20 am

  3. Tracy,

    Interesting verb, and interesting example of use. Being addicted to brevity, I might phrase it thus:

    ifMissing =: ,&<~ {::~ 0 e. $@]

    Comment by Dan Bron — October 22, 2009 @ 8:58 am

RSS feed for comments on this post.

Leave a comment

Powered by WordPress