Why Number(symbol) crashes?

# medikoo (8 years ago)

I was searching the archived but wasn't able to find the answer.

What's the reasoning behind having Number(symbol) crash instead of returning NaN (as it's in case all other non-coercible values?). It feels not consistent.

If someone can point me to some discussion that provided the reasoning I'd be grateful

-- View this message in context: mozilla.6506.n7.nabble.com/Why-Number-symbol-crashes-tp359554.html Sent from the Mozilla - ECMAScript 4 discussion mailing list archive at Nabble.com.

# Kris Siegel (8 years ago)

Symbol is such an oddball; similar to this if you do Symbol() + "" it will also throw an exception unlike all other built-ins. Granted I have no idea what a string representation of Symbol really would be but no other built in type behaves the way Symbol does.

I do think Number(Symbol()) should return NaN though. I'd like to know why this didn't happen.

# Oriol Bugzilla (8 years ago)

In my opinion it's a bit incoherent that each object-coercible type behaves differently when coercing symbols to it.

Symbols can be explicitly coerced to strings, but not implicitly:

String(Symbol("abc")); // "Symbol(abc)"
Symbol("abc") + ""; // TypeError

Symbols can't be coerced to numbers, neither explicitly nor implicitly:

Number(Symbol("abc")); // TypeError
+Symbol("abc"); // TypeError

Symbols can be coerced to booleans, both explicitly and implicitly:

Boolean(Symbol("abc")); // true
!!Symbol("abc"); // true

Maybe the Number constructor could behave analogous to String and return NaN for symbols, instead of calling ToNumber.

# Raul-Sebastian Mihăilă (8 years ago)

How is NaN useful? Isn't it better to be explicit if you really want a string?

# Jordan Harband (8 years ago)

I'm not sure what you're asking. Number(Symbol()) throws a TypeError.

Perhaps are you using a Symbol sham (that only partially is able to polyfill Symbols)?

In what browser/engine are you seeing NaN?

# Jordan Harband (8 years ago)

whoops, sorry, I missed the earlier thread. disregard.

# Claude Pache (8 years ago)

Le 11 oct. 2016 à 11:07, medikoo <medikoo+mozilla.org at medikoo.com> a écrit :

I was searching the archived but wasn't able to find the answer.

What's the reasoning behind having Number(symbol) crash instead of returning NaN (as it's in case all other non-coercible values?). It feels not consistent.

If someone can point me to some discussion that provided the reasoning I'd be grateful

I believe that the reason of the inconsistency is more an accident of history in the development of ES6 than a well-reasoned design decision. Here is my understanding:

  • At one point of time in the development of ES6, /implicit/ conversion from symbol to string or number was made forbidden. This is a behaviour that was discussed and decided, in order to prevent silent bugs in computed properties in situations where a string was previously implicitely expected.
var key = Symbol()
foo[‘key + ‘-suffix’] // TypeError: can’t convert symbol to string
foo[‘key + ‘42] // TypeError: can’t convert symbol to number
  • However, /explicit/ conversion from symbol to string (using String(…) or .toString()) has been kept as allowed. This is a more debatable decision (with pros and cons). On the other hand, I don’t recall any discussion about making explicit conversion from symbol to number different from the implicit one, nor anyone complaining that it remained the only primitive type to which symbol could not be explicitly coerced.
# Allen Wirfs-Brock (8 years ago)

On Oct 14, 2016, at 11:02 AM, Claude Pache <claude.pache at gmail.com> wrote:

Le 11 oct. 2016 à 11:07, medikoo <medikoo+mozilla.org at medikoo.com> a écrit :

I was searching the archived but wasn't able to find the answer.

What's the reasoning behind having Number(symbol) crash instead of returning NaN (as it's in case all other non-coercible values?). It feels not consistent.

If someone can point me to some discussion that provided the reasoning I'd be grateful

I believe that the reason of the inconsistency is more an accident of history in the development of ES6 than a well-reasoned design decision. Here is my understanding:

No this was an intentional design decision. There is no obvious or natural Number value corresponding to symbol values. Rather than inventing some arbitrary conversion rule (for example producing NaN) TC39 choose to throw an exception for such conversions as they are a clear manifestation of some sort of program bug.

Note that the coercion rules for the original JS primitive types were created at a time when JavaScript did not have an exception handling mechanism and hence all operations were required to produce some value. Throwing exceptions for unreasonable Symbol coercions is intentionally inconsistent with the handling of the original primitive coercions and is intended to set a new precedent that will be applied to any other new primitive types that might be added to ES in the future.

# Michał Wadas (8 years ago)

To be honest, introducing new throw-on-invalid value behaviour to existing function that didn't throw before looks rather like a bad design for me. Personally I wouldn't abandon accept-anything behaviour of Number, but rather add method Number.from that will throw on all values that shouldn't be coerced to number.

# medikoo (8 years ago)

Allen, thanks for comprehensive answer, it's clear now.

Still, I must agree with Michał, that introducing such inconsistency to language doesn't give good impression. It's like we try to build other language on top of language which we can't change.

It's now even more difficult to explain language behaviors to newcomers.

-- View this message in context: mozilla.6506.n7.nabble.com/Why-Number-symbol-crashes-tp359554p359653.html Sent from the Mozilla - ECMAScript 4 discussion mailing list archive at Nabble.com.