Brendan Eich (2013-09-07T19:22:35.000Z)
domenic at domenicdenicola.com (2013-09-18T19:00:54.928Z)
This is intentional and dates to ES1. It arises because the `&&` and `||` operators are value-preserving (as in Perl and various Lisps) as well as short-circuiting (as in C). Suppose we have ```js var obj = {valueOf: function(){return Math.random() < 0.5}}; var huh = (obj || foo) && bar; ``` If `obj.valueOf()` were called during the temporary implicit conversion to boolean, and its return value were truthy, then `foo` would not be evaluated and control would jump to the `&& bar` -- but with the result of `(obj || foo)` not being `true`, rather being `obj`. Then `&&` would have to evaluate `obj` by implicitly converting it to boolean, and under the hypothesis call `valueOf()`. The problem is that implicit conversion, which if customizable (e.g., by `valueOf`) cannot be idempotent in general, must apparently be done more than once -- even though there is only one `obj` term in the whole chain. This is a consequence of the value-preserving on top of short-circuiting nature of `&&` and `||`. I argued for implementations being required to memoize implicit conversion results so no each term is implicitly converted at most once, in order to enable conversion to boolean being customizable via `valueOf`. My TC39 TG1 peer from Microsoft argued that we should throw out the value-preserving semantics of `&&` and `||`. In order to keep those, I conceded. In the value objects strawman I'm working on, `!` and `!=` are not overloadable. Boolean test is overloadable, though, so `0L`, `0UL`, `0m`, etc. can be falsy. Without reopening this ancient ES1 conflict, I hope to find a solution that does not complicate the semantics with memoization of implicit conversion results.