Eager boolean operators in JavaScript

In most programming languages like Java, JavaScript, C and C#, the boolean operators && and || perform short-circuited evaluation. Essentially, this means that a program, when evaluating boolean operators, will only evaluate as many arguments as is necessary to determine the value of a boolean expression. Sometimes, however, this is not the behaviour we want.

In this article we will look at how to implement non-short-circuited or “eager” versions of the JavaScript boolean operators && and ||.

As mentioned earlier, most programming languages have short-circuited boolean operators. Short-circuited operators are possible due to certain properties of conjunctions and disjunctions in Boolean logic. In Boolean logic, for a conjunction x1 && x2, if the first argument evaluates to false, the whole expression will be false, regardless of what the other argument evaluates to. Similarly, for a disjunction x1 || x2, if the first argument evaluates to true, the whole expression will be true, regardless of what the other argument evaluates to.

For a more concrete example, consider this snippet of JavaScript:

var str = null;
if (str !== null && str.length > 0) {
    alert("String is not null or empty");
} else {
    alert("String is null or empty");
}

If executed by a browser, this snippet will alert String is null or empty. It does not throw a TypeError when it hits str.length because str.length is never evaluated. The JavaScript interpreter skips it once it sees str !== null evaluates to false. This is an advantage of short-circuiting.

What if we don’t want to short the circuit?

Although short-circuiting is almost always what we want, there are rare instances where we may want to have non-short-circuited or eager evaluation. Consider this example using jQuery:

var validate = function(element) {
    if (element.val() === "") {
        element.addClass("invalid");
        return false;
    } else {
        element.removeClass("highlight");
        return true;
    }
};
 
var form = $("#comments-form");
var name = form.find("#name");
var email = form.find("#email");
var comments = form.find("#comments");
 
form.submit(function() {
    return validate(name) && validate(email) && validate(comments);
});

In this example, we are validating a comments form for a website. In order to do that, we use a validate function to verify that an HTML input is not empty. If it is empty, then we add a CSS class to highlight it and then return false to indicate validation failed. Conversely, if it’s not empty, we remove the highlight CSS class and then return true to indicate validation succeeded.

Unfortunately, this code will only highlight the first field that fails validation. Why? Because the && short-circuits the first time it evaluates an argument to false and thus the rest of the validations will not be executed.

So how do we force them run? Well, if we were using a language like Java or C#, we would simply use the & and | operators, which are eager versions of the short-circuited && and || operators. Unfortunately, although JavaScript does provide the & and | operators, they return numeric (0 or 1) instead of boolean (true or false) results.

Eager boolean operators in JavaScript

(Aside: In the following section I use the arithmetic operators * and + to emulate eager boolean operators. You can just as easily use the bitwise operators & and | in their place. The only reason I used the arithmetic operators was because I thought they would make for a more interesting article).

So we’ve established that JavaScript has no eager boolean operators. JavaScript does, however, offer us two arithmetic operators that can almost accomplish our goal: * and +. These operators, in conjunction with JavaScript’s type coercion semantics, produce the following truth tables when fed all combinations of true and false (&& and || are shown for comparison):

a b a && b a * b a || b a + b
false false false 0 false 0
false true false 0 true 1
true false false 0 true 1
true true true 1 true 2

In the table you’ll notice that * and + operators yield almost identical truth tables to the && and || operators, with the exception being that the short-circuited operators produce boolean values (true and false) while the arithmetic operators produce integer values (0, 1 or 2). Moreover, unlike the boolean operators, the arithmetic operators are eager.

That means that, in order to use the arithmetic operators to implement eager boolean operators that produce the exact same results as the built-in boolean operators, we need to map 0 to false and map any non-0 values to true. Fortunately, this is exactly what JavaScript’s type coercion does when forced to coerce a number into a boolean, which can be accomplished by prefixing the number with two ! operators.

a b a && b !!(a * b) a || b !!(a + b)
false false false false false false
false true false false true true
true false false false true true
true true true true true true

And there we have it. We’ve implemented eager boolean operators using JavaScript’s type coercion, the arithmetic operators * and + and the logical not operator !.

Conclusion

Boolean operators in most programming languages are short-circuited: they evaluate their terms left to right and stop (i.e. short-circuit) once they can definitively determine the truth value of expression. This behaviour is usually what we want. However, in some rare cases, we want to evaluate all terms in a boolean expression. Such an operator is called an eager boolean operator.

Although JavaScript does not provide eager boolean operators, they can be emulated by using a combination of JavaScript’s type coercion semantics and arithmetic and logical operators.

12 Comments so far

  1. Zecc on September 10th, 2010

    I know this is hardly the point of your article, but this is how you would do it without compromising readability:

    form.submit(function() {
    	var valid = true;
    	valid = validate(name) && valid;
    	valid = validate(email) && valid;
    	valid = validate(comments) && valid;
        return valid;
    });
  2. Peter da Silva on September 10th, 2010

    Is there some technical reason you used !!(a+b) and !!(a*b) instead of the more obvious !!(a|b) and !!(a&b)?

  3. Joshua on September 10th, 2010

    I understand your reason for this but it seems like a bad solution to a simple problem.

    If you want to change the state of things then performing them in a compound if statement in a language that doesn’t natively support it seems wrong, and it makes the code less readable.

    Why not just perform the operations and check the returned values seperately. It would be more readable and would not require double negating a mathematical function.

  4. mbielski on September 10th, 2010

    Very interesting article. Think I’ll share this one around my web developers group.

  5. Concerned on September 10th, 2010

    This is ridiculous.

    The only reason you want eager evaluation is to cause side effects.

    Bad programmer!

  6. Gene Pharr on September 10th, 2010

    OR you can just exectute each term of your expression and assign it to a temporary “accumulator” boolean variable prior to the final use of the accumulated truth value.

    “return A && B && C;” Becomes:

    “D = A;”
    “D &= B;”
    “D &= C;”
    “return D;”

    This is a lot more readable, and SHOULD BE COMMENTED to note the need for the guaranteed evaluation of all three terms so that some future maintainer of the application won’t thoughtfully combine them into a single line of unreadable gibberish.

  7. nick on September 10th, 2010

    good article. stuff like this in javascript is constantly surprising me.

    I would however argue that using the arithmetic ops make it less clear when reading the code. and it seems like javascript programmers are always trying to make things as terse as possible, hence the ‘return validate(name) && validate(email) && validate(comments);’, which might clearer if each validate statement were executed separately and then the results &&ed together – which would also remove the need for eager eval.

    But it’s good to know that this is an option.

  8. Ygor on September 10th, 2010

    Cool!

    Since I don’t know about how javascript performs coercion, I have one question: relatively speaking, will be slower to do things this way?

  9. cdmckay on September 10th, 2010

    @Peter da Silva: I used and * just to show that the arithmetic operators could be used. You are correct that the bitwise | and & operators could easily be used in their place.

    @Joshua: I agree that side effects make code confusing to follow. I was using a contrived example to demonstrate a case when you might want to use an eager boolean operator.

    @Concerned: I think you misunderstood the point of the article. I was not advocating that you should program with side effects. I was merely presenting a contrived situation where you might be want eager boolean operators.

    @Ygor: I’m not sure of how much of a penalty type coercion incurs, but I have a feeling it’s pretty low as it happens quite a bit in JavaScript.

  10. [...] This post was mentioned on Twitter by Manish Deo, iofit. iofit said: Eager boolean operators in JavaScript » Cameron McKay http://bit.ly/bJiRAx [...]

  11. SeanJA on September 12th, 2010

    Shouldn’t the code for the “What if we don’t want to short the circuit?” validation function return false when it is invalid instead of true? That way the form won’t be submitted when the values are empty.

  12. cdmckay on September 13th, 2010

    @SeanJA: Whoops. You’re correct, that function should return opposite truth values. I’ll fix it now.

Leave a reply

*