Boolean objects in conditionals

Brendan Eich brendan at
Fri Nov 28 18:17:36 PST 2008

On Nov 28, 2008, at 5:07 PM, Peter Michaux wrote:

> On Fri, Nov 28, 2008 at 2:20 PM, Lasse R.H. Nielsen
>> If objects are no longer all "true", then I would prefer each  
>> object to
>> be able to decide its truth value.
> An object's toString method is called when the object is coerced to a
> string. Why not toNumber and toBoolean?

An object has valueOf(hint) for the former. In ES1 we agreed not to  
convert object to boolean, to avoid re-conversion in expressions such  
as the right-hand side of the final assignment in this program:

a = {valueOf: function(hint){if (hint == "boolean")return false;  
return 42}};
b = falsy();
c = truthy();
x = (a && b) || c;

Evaluating (a && b) would, if we converted object to boolean using  
valueOf, convert a to false to decide whether to short-circuit and  
yield false instead of evaluating b. But the result of (a && b) would  
still be the reference to the object denoted by a -- the result would  
not be false.

Then we would evaluate (a || c) which would convert a to boolean  
again, getting false and not short-circuiting evaluation of c. The  
result of the whole thing stored in x would be whatever c evaluated to.

Because the object denoted by a could convert several times, some  
members of TC39 at the time (esp. Shon of Microsoft) objected. No  
other conversion/operator combo has such a multiple-implicit-calls-in- 
an-expression-where-denoted-once property.

Efficiency might favor caching intermediates but that would be  
detectable if the valueOf function has effects. The spec can't mandate  
caching or not-caching, so the degree of freedom here would degrade  
interoperation marginally. Anyway mutation makes the multiple calls  
particularly hazardous compared to other conversion/op pairs.

This may seem like too minor or abstract a point to get hung up on,  
but it almost broke the standardization of && and || as Perl-ish value- 
preserving multiplexing operators.

I don't see a way to overcome this objection, and I don't think it's  
in anyone's interest to allow object-to-false custom conversion at  
this stage. There are falsy-object use cases, but they're rare. The  
boolean primitive, if modeled as an object (we did this in ES4's RI),  
is unique among the built-ins. Bridging to other languages may be a  
use-case for implicit conversion from object to boolean, but these  
bridge cases usually involve deep magic not expressible in JS.

Since we have valueOf and will in Harmony, I see little gain and much  
complexity in adding toNumber or anything else, never mind toBoolean.  
The big lesson here is EIBTI (google it). Enough implicit conversions!


More information about the Es-discuss mailing list