Boolean objects in conditionals

Brendan Eich brendan at mozilla.com
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!

/be


More information about the Es-discuss mailing list