Short-circuits and the ternary operator

Recently I added support for the C-style ternary [I always say 'trinary'] operator ?: to Jujuscript… it was just one of those things that I’d been putting off for years, but I finally did it [surprisingly painlessly]. The ?: operator creates a conditional-expression, allowing you to do the following:

return a ? b : c;

If a is ‘true’ here, then we return b, otherwise we return c. Without the ?: operator we would have to write:

if (a)
return b;
else
return c;

Neat, huh?

Short-circuiting

Since the ?: operator was a success, I then went on to add support for another aspect of C which I had been long ignoring: the short-circuiting && and || operators [also particularly neat].

Short-circuiting is a great feature of C/C++ which means that the minimum amount of processing is done in boolean expressions. Short-circuiting allows expressions like this to be used:

if (ob && ob->member == 1)
// do stuff

Here ob is first tested to see if it is non-NULL, and only if this is the case will its member be tested. Without short-circuiting this expression would cause an exception when ob is NULL, and so it would have to be replaced with the clumsier:

if (ob)
if (ob->member == 1)
// do stuff

Similarly, the logical-OR operator can simplify your code.

if (string == "end" || string == "eof")
// do stuff

In this example, if string is "end" then the second comparison is never performed, thus saving valuable clock cycles.

Beyond C…

In C, the && and || operators return boolean values only. So yes, they’re neat, but not as neat as they could be.

In Jujuscript [and Perl and Python and probably others] these operators actually return the last value evaluated. So (2 || 3) returns 2, and (2 && 3) returns 3 [whereas in C they would both simply return true]

This extra flexibility allows for constructs such as this:

return sz || "default"

In this example, if sz is non-NULL then sz will be returned, otherwise "default" will be returned. To achieve the same result in C you have to use the slightly less convenient form:

return sz ? sz : "default"

For a brief period of time, I actually thought these new operator behaviours might allow me to dispense with the ternary ?: operator [which I only just added...programmers love throwing away code, even if they've only just written it].

remember that although the syntax and operators are C-like, this is not C, and the && and || operators can return other types besides bool

return c ? (b=3) : (a=4);
return c && (b=3) || (a=4);

In this case the 2 forms produce exactly the same results (both will only modify a or b depending on the value of c, and return the new a or b). In spite of this, can you see why they are NOT equivalent? It took me a while to notice…

ANSWER: The two expressions are only equivalent if the value of the second component [in this case (b=3)] can be considered true. If it is not, the expression will "fall through" and return the value of the third component, regardless of the value of the test expression.