typeof symbol (Was: Sept 19 TC39 Meeting Notes)
Tom Van Cutsem wrote:
2012/9/29 Andreas Rossberg <rossberg at google.com <mailto:rossberg at google.com>>
On 28 September 2012 18:28, Tom Van Cutsem <tomvc.be at gmail.com <mailto:tomvc.be at gmail.com>> wrote: > I agree that proxying a symbol is of little value, but I didn't say that > symbols are closer to strings than to objects. I think symbols are closer to > objects: they have an unforgeable identity. Strings don't have that, objects > do. I don't follow how generative creation is synonym to "identity", nor how identity implies being an object. Should we make everything an object just because we can? For symbols in particular I completely fail to see a good reason for doing so (now that we are able to drop the "public" name property). It will just induce extra cost for dubious semantic value -- or actually, semantic cost, as the issue of proxying them indicates.
I'm not against thinking of symbols as an entirely new "class" of values. I was mostly arguing against the idea of having typeof symbol be "string". If there are good reasons for symbols not to get their own typeof type, I just think "object" would be more reasonable than "string".
When I though of this (from the user PoV), it seems to me that in fact, symbols are closer to strings. I see it this way:
- closer to object === "symbol have its own identity, state and behaviour, I can add new properties and methods etc." (an array is good example of this, if you consider what it can do beyond elements and length)
- close to string === "symbol have its own identity and a little more than that"
IOW, it seems to me that symbols are more like "parallel" set of strings, of which every new one is different ("has different sequence of chars"), but it does not carry all the other "object-like" traits with it. More or less, only things that matters if if a symbol a === a symbol b. Which I see as string-like, not an object-like.
But, again, this is less technical and more feeling.
On Sat, Sep 29, 2012 at 9:34 AM, Herby Vojčík <herby at mailbox.sk> wrote:
Tom Van Cutsem wrote:
2012/9/29 Andreas Rossberg <rossberg at google.com <mailto:rossberg at google.com>>
On 28 September 2012 18:28, Tom Van Cutsem <tomvc.be at gmail.com <mailto:tomvc.be at gmail.com>> wrote: > I agree that proxying a symbol is of little value, but I didn't say that > symbols are closer to strings than to objects. I think symbols are closer to > objects: they have an unforgeable identity. Strings don't have that, objects > do. I don't follow how generative creation is synonym to "identity", nor how identity implies being an object. Should we make everything an object just because we can? For symbols in particular I completely fail to see a good reason for doing so (now that we are able to drop the "public" name property). It will just induce extra cost for dubious semantic value -- or actually, semantic cost, as the issue of proxying them indicates.
I'm not against thinking of symbols as an entirely new "class" of values. I was mostly arguing against the idea of having typeof symbol be "string". If there are good reasons for symbols not to get their own typeof type, I just think "object" would be more reasonable than "string".
When I though of this (from the user PoV), it seems to me that in fact, symbols are closer to strings. I see it this way:
- closer to object === "symbol have its own identity, state and behaviour, I can add new properties and methods etc." (an array is good example of this, if you consider what it can do beyond elements and length)
- close to string === "symbol have its own identity and a little more than that"
IOW, it seems to me that symbols are more like "parallel" set of strings, of which every new one is different ("has different sequence of chars"), but it does not carry all the other "object-like" traits with it. More or less, only things that matters if if a symbol a === a symbol b. Which I see as string-like, not an object-like.
But, again, this is less technical and more feeling.
Yes, there are certainly a number of both objective and subjective arguments that could be had about this topic.
If Symbol does not have the built-in String prototype object as its [[Prototype]] or in its chain, then typeof symbol should not return "string".
The private name objects proposal specifies that Symbol (as Name) properties will be treated differently then string properties and even describes a new internal operation to supplant ToString's role in property lookup[0].
Offline discussion with Dave that immediately identified a deal-breaker: if typeof symbol were "string", it would break ===.
=== for strings is based on their contents === for objects is based on their identity
Rick
Herby Vojčík wrote:
- closer to object === "symbol have its own identity, state and behaviour, I can add new properties and methods etc." (an array is good example of this, if you consider what it can do beyond elements and length)
- close to string === "symbol have its own identity and a little more than that"
IOW, it seems to me that symbols are more like "parallel" set of strings, of which every new one is different ("has different sequence of chars"), but it does not carry all the other "object-like" traits with it.
That still leaves open the possibility that someone could forge a string equal to the symbol, which is not possible.
More or less, only things that matters if if a symbol a === a symbol b. Which I see as string-like, not an object-like.
No, symbols are not strings.
-
You can't forge a symbol, but you can easily make up any string, with some effort brute-force-attack a secret string, etc.
-
Symbols do not get auto-wrapped by String wrappers (or appear to be auto-wrapped) such that String.prototype methods work.
I agree with Tom, "object" is the best choice if we are to avoid extending typeof's codomain. If we choose to extend, then your best case made above arguess for "symbol", not "string".
I agree with Tom, "object" is the best choice if we are to avoid extending typeof's codomain. If we choose to extend, then your best case made above arguess for "symbol", not "string".
I’ve been wondering: instead of fixing typeof, wouldn’t it be simpler to extend instanceof, by introducing new types:
- ReferenceType: to check whether a value is an object. Currently, objects such as Object.create(null) and Object.prototype are objects that are not instanceof Object.
- ValueType: for primitives and possibly future value objects.
- PrimitiveBoolean: for primitive booleans, same as typeof x === 'boolean'
- etc.
Should there ever be guards in the future, instanceof MyGuard would also make sense.
Axel
Rick Waldron wrote:
Offline discussion with Dave that immediately identified a deal-breaker: if typeof symbol were "string", it would break ===.
=== for strings is based on their contents === for objects is based on their identity
That's true but I think it has not to do with ===. It's because symbols must not be forgeable by spelling out any "contents" or "value" that can == or === another symbol's contents/value.
The invariant that applies:
(typeof x == typeof y && x == y) <=> (x === y).
This would hold even if typeof returned "string" for a symbol, so long as that symbol was == and === only itself.
It obviously also works if typeof returns "object" for a symbol, as in the current proposal.
In the sense that "abc" === "ab" + "c" then of course Dave's right. You can't do any such thing with a symbol. But so long as unforgeability is upheld, this issue is not about === (or ==). It's about typeof returning "string" for a symbol, a bad idea.
The lack of String.prototype delegation as if by auto-wrapping is a second deal-killer.
Between "object" and a new typeof result, "symbol", the safer course is "object".
For value objects such as int64 and uint64, I've come to believe that the invariant above conjoined with
(0L == 0UL) === true
being the desirable == but not === behavior requires typeof 0L => "int64" and typeof 0UL => "uint64.
Value objects have content-based identity, but they're objects. Symbols could be viewed as objects and identity and typeof all work "for free".
To resolve Andreas's concern about cost of object, we could say that Symbols are frozen and empty. That would be enough to optimize as hard as possible.
Axel Rauschmayer wrote:
I agree with Tom, "object" is the best choice if we are to avoid extending typeof's codomain. If we choose to extend, then your best case made above arguess for "symbol", not "string".
I’ve been wondering: instead of fixing typeof, wouldn’t it be simpler to extend instanceof, by introducing new types:
- ReferenceType: to check whether a value is an object. Currently, objects such as Object.create(null) and Object.prototype are objects that are not instanceof Object.
This doesn't work with value objects, and anyway doesn't work by testing proto-chain membership starting from RHS.prototype where RHS is the constructor function.
- ValueType: for primitives and possibly future value objects.
- PrimitiveBoolean: for primitive booleans, same as typeof x === 'boolean'
Again, we cannot inserte more prototypes on existing proto-chains.
- etc.
Should there ever be guards in the future, instanceof MyGuard would also make sense.
If you are not using the proto-chain, then what? What's the underlying theory for extending instanceof?
Compatibility concerns make this a non-starter, IMHO. We'd do better to keep instanceof simple and extend typeof. IE already has extra typeof results so developers have to beware.
On Sat, Sep 29, 2012 at 11:52 AM, Brendan Eich <brendan at mozilla.org> wrote:
Rick Waldron wrote:
Offline discussion with Dave that immediately identified a deal-breaker: if typeof symbol were "string", it would break ===.
=== for strings is based on their contents === for objects is based on their identity
That's true but I think it has not to do with ===. It's because symbols must not be forgeable by spelling out any "contents" or "value" that can == or === another symbol's contents/value.
The invariant that applies:
(typeof x == typeof y && x == y) <=> (x === y).
This would hold even if typeof returned "string" for a symbol, so long as that symbol was == and === only itself.
It obviously also works if typeof returns "object" for a symbol, as in the current proposal.
In the sense that "abc" === "ab" + "c" then of course Dave's right. You can't do any such thing with a symbol. But so long as unforgeability is upheld, this issue is not about === (or ==). It's about typeof returning "string" for a symbol, a bad idea.
The lack of String.prototype delegation as if by auto-wrapping is a second deal-killer.
Between "object" and a new typeof result, "symbol", the safer course is "object".
For value objects such as int64 and uint64, I've come to believe that the invariant above conjoined with
(0L == 0UL) === true
being the desirable == but not === behavior requires typeof 0L => "int64" and typeof 0UL => "uint64.
Value objects have content-based identity, but they're objects. Symbols could be viewed as objects and identity and typeof all work "for free".
To resolve Andreas's concern about cost of object, we could say that Symbols are frozen and empty. That would be enough to optimize as hard as possible.
Half way there :) The proposal describes them as "deeply frozen"
Axel Rauschmayer wrote:
I agree with Tom, "object" is the best choice if we are to avoid extending typeof's codomain. If we choose to extend, then your best case made above arguess for "symbol", not "string".
I’ve been wondering: instead of fixing typeof, wouldn’t it be simpler to extend instanceof, by introducing new types:
- ReferenceType: to check whether a value is an object. Currently, objects such as Object.create(null) and Object.prototype are objects that are not instanceof Object.
This doesn't work with value objects, and anyway doesn't work by testing proto-chain membership starting from RHS.prototype where RHS is the constructor function.
- ValueType: for primitives and possibly future value objects.
- PrimitiveBoolean: for primitive booleans, same as typeof x === 'boolean'
Again, we cannot inserte more prototypes on existing proto-chains.
- etc.
Should there ever be guards in the future, instanceof MyGuard would also make sense. If you are not using the proto-chain, then what? What's the underlying theory for extending instanceof?
The idea would be to not use the proto chain (which would be odd for primitive values, anyway), to make these “pseudo-types” special.
Compatibility concerns make this a non-starter, IMHO. We'd do better to keep instanceof simple and extend typeof. IE already has extra typeof results so developers have to beware.
Extending instanceof would result in something that is more consistent. It would allow less experienced programmers to ignore the difference between primitives and objects (which you almost can now in JavaScript, in stark contrast to, say, Java).
Axel
Axel Rauschmayer wrote:
What's the underlying theory for extending instanceof?
The idea would be to not use the proto chain (which would be odd for primitive values, anyway), to make these “pseudo-types” special.
That's not much of a theory :-P. So hardcode two or three special cases? Yikes.
Brendan Eich wrote:
Herby Vojčík wrote:
- closer to object === "symbol have its own identity, state and behaviour, I can add new properties and methods etc." (an array is good example of this, if you consider what it can do beyond elements and length)
- close to string === "symbol have its own identity and a little more than that"
IOW, it seems to me that symbols are more like "parallel" set of strings, of which every new one is different ("has different sequence of chars"), but it does not carry all the other "object-like" traits with it.
That still leaves open the possibility that someone could forge a string equal to the symbol, which is not possible.
More or less, only things that matters if if a symbol a === a symbol b. Which I see as string-like, not an object-like.
No, symbols are not strings.
No, they're not, of-course. I'd say they string-like (more than object-like).
If you say strings have content and are forgeable, that shows that what I wanted to say, is something slightly different. Basically I wanted to say that such entities (where identity is only thing they have; which seemed for me closer to string than to object) are "atoms" (maybe they can have typeof "atom" with future possibility to use it for other such beasts, if they occur beyond symbols).
But OTOH, all primitives are "atoms" in this view (strings, too). The only difference is, if they are forgeable (that is, I can produce them by some operations, like +, from their peers). If fact, I don't see this as distiguishing property enough. The nature of "I hold no subvalues, my identity is my value" is what separates primitives from objects (or maybe not primitives, but atoms, and primitives <= atoms), not the forgeability.
So, symbols look to me more like primitives/atoms (that means, not an object nor function) and so they should have their own typeof...
Herby Vojčík wrote:
So, symbols look to me more like primitives/atoms (that means, not an object nor function) and so they should have their own typeof...
That's progress, if you agree typeof aSymbol should not return "string" ;-).
However, what you say about "I hold no subvalues, my identity is my value" can fit an empty frozen object too.
Anyway if you feel strongly typeof should return "symbol" not "object" we have to face the dragons around the edge of the known typeof map. Fortunately IE shipped some in the known world. I could buy "symbol" but I'm also inclined toward "int64", "uint64", and other value-object typeof results in the future.
The hard thing is the non-zero risk of breaking some code by officially extending typeof, vs. the zero risk of using "object". The latter won't break any code that already might fail due to the full range of {null, pre-ES5 objects, frozen/sealed via ES5 API usage objects}.
Brendan Eich wrote:
Herby Vojčík wrote:
So, symbols look to me more like primitives/atoms (that means, not an object nor function) and so they should have their own typeof...
That's progress, if you agree typeof aSymbol should not return "string" ;-).
However, what you say about "I hold no subvalues, my identity is my value" can fit an empty frozen object too.
Anyway if you feel strongly typeof should return "symbol" not "object" we have to face the dragons around the edge of the known typeof map. Fortunately IE shipped some in the known world. I could buy "symbol" but I'm also inclined toward "int64", "uint64", and other value-object typeof results in the future.
Not strongly. But philosophically they seems like kind of (unforgeable) primitives. Conceptually, they could be either fill objects (I can add properties to them and thus use them not only as unique symbols but also as holders/namespaces/communication channels) or their nature is "my identity is my only value".
Both are fine, but I think typeof should be "object" if it is the former (they are objects then), but should be "symbol" if the former (because then, they are atoms).
Frozen empty object can be created, and technically it has same properties, but it seems to me as an abuse of object. I'd like to see rise of use of symbols not only as unique (private) names, but also for other atom-like places, as a sentinels, for example (where such empty frozen objects were used before, or primitives like null or empty string).
The hard thing is the non-zero risk of breaking some code by officially extending typeof, vs. the zero risk of using "object". The latter won't break any code that already might fail due to the full range of {null, pre-ES5 objects, frozen/sealed via ES5 API usage objects}.
It's political decision, others may say what they think. I formulated what I see conceptually, what would make me feel that the logic behind the ES6 is not so hairy (well, null :-/ but it can't be helped). Of course, there are pragmatic, technical decisions they may break the desire for beautiful systematics.
Herby Vojčík wrote:
Frozen empty object can be created, and technically it has same properties, but it seems to me as an abuse of object.
Not at all, JS always allowed a unique object to be made as a guaranteed sentinel. That was a feature, and of course typeof sentinel == "object".
I think this is too philosophical a discussion to result in a strong reason to risk "symbol". Just my gut-check. Other TC39ers should weigh in (Andreas R. especially).
I think typeof should be simplified, focusing more on instanceof: typeof should only return "undefined", "string", "number", "boolean" and "object".
var fn = function () { }; fn instanceof Function // true fn instanceof Object // true
Because typeof returns a string it is never true for two different types, so instanceof is more detailed. Problems would be that Null, NotANumber, Infinity habe to be functions, so that a null can also be instanceof an Object and a NaN instanceof NotANumber Number Object. Using an Int64 Function where the prototype is Number, we could also have an instanceof Int64 Number Object.
I'm also tweaking around instanceof in my article on metadea.de/V/default.aspx#V_construct_and_your_class ... please see how I'm creating 'class' functions, having real OOP in jS, using instanceof, featuring reflection using a V.Construction Object class info (that is also used for prototyping a base function) and an the implicit instanceOf and constructionOf functions. Without hacking around proto .
However I'd like to say that in the part of "Why javaScript typeof operator should be deprecated" I didn't thought properly about primitives and the usage of the operators that my idea would completely break ;) So please read that part with this warning in mind, but there are also some thoughts on primitives that are boxed to Object. To say simple what I need to change in the ...deprecated... part is, that typeof and primitives should keep, but the constructor and the primitives corresponding Object instances should be the way described.
Uli
You may have missed the 1JS and typeof null messages. We cannot remove "function" or make any other such backward-incompatible change. But we could add new results.
The problem with instanceof is that it fails cross frame.
The invariant two-way implication relating == and === that I gave is important, and for value objects such as int64 and uint64 I argue it implies new typeof results.
What if the semantics were fixed specifically with egal operators?
if ( typeof null is "null" )
Axel Rauschmayer wrote:
What's the underlying theory for extending instanceof?
The idea would be to not use the proto chain (which would be odd for primitive values, anyway), to make these “pseudo-types” special.
That's not much of a theory :-P. So hardcode two or three special cases? Yikes.
With contracts/guards, it would be more than three cases. One could always introduce a protocol. I’m not saying that that’s the (only) way to do it, I’m just saying that it would be nice not to have to deal with the current “cross-frame, primitive vs. object, [[Class]] vs. instanceof” mess. typeof is already hard-coded.
The problem with instanceof is that it fails cross frame.
Won’t that go away (long-term) with postMessage?
Matthew Robb wrote:
What if the semantics were fixed specifically with egal operators?
if ( typeof null is "null" )
Not sure what you're saying here -- was your message cut off?
We're probably not adding 'is' and 'isnt' operators with restricted productions (no Line Terminator to left). Object.sameValue as polyfillable API is enough. But this doesn't change a thing about ==, === and typeof.
Axel Rauschmayer wrote:
The problem with instanceof is that it fails cross frame.
Won’t that go away (long-term) with postMessage?
What do you mean? If in the very long run no cross-frame same-origin object sharing occurs? I think that's a dream.
You may have missed the 1JS and typeof null messages. We cannot remove "function" or make any other such backward-incompatible change. But we could add new results. Have a new favorite ;) For others reading this (was hard to find using G, search for ‘ ”One JavaScript” dherman ‘): dherman/tc39-codex-wiki/blob/master/data/about/faq.md The problem with instanceof is that it fails cross frame. Yes, cross frame I didn’t check out yet, but it’s a clear problem...
In the way V.construct prepares a function, it adds a V.Construction Object to the class Function and validates the supplied globalName string to be global evaluable. So for example V.Ex.ArgumentNot Function has a construction property, that will be (new V.Ex.ArgumentNot(‘arg’)).constructor.construction. In that V.Construction Object is the validated globalName stored (as string). To have shorter access, V.construct adds implicit functions to the class function, and also to the prototype for new class objects. The V.Ex.ArgumentNot.constructionOf respectively (new V.Ex.ArgumentNot).instanceOf functions return implicit the globalName, or return a bool if the supplied argument is a valid inherited function-type globalName string.
So if I get an ex from another frame, I could check if ex instanceOf(‘V.Ex.ArgumentNot’), if ex instanceof(‘V.Ex.InvalidInstanceof’) or if ex instanceof(‘V.Ex’). I can also check ex.instanceOf === ‘V.Ex.ArgumentNot’. To recreate an object of this type, var fn = V.evalName(‘V.Ex’); var ex = new fn() would re-create a frame-local V.Ex Object.
It’s bad... but ways better than typeof. I don’t think typeof should be extended, it always returned lower cased names and not the upper cased string, that would be representative for the primitives global functions (‘object’ and not ‘Object’). The evaluable globalName that V.construct validates is re-expressive. It isn’t only a string, it is a name that evaluated to window points to the class Function. I understand that instanceof won’t be cross-frame capable, however using a global evaluable name, someone who knows that he is talking cross frames may consider using implicit instanceOf([String]) function instead of instanceof Function operator.
Uli
-----Ursprüngliche Nachricht---
Uli Riehm wrote:
It’s bad... but ways better than typeof. I don’t think typeof should be extended, it always returned lower cased names and not the upper cased string,
No one is proposing that typeof return capitalized strings or anything that might be a constructor name in a global object.
The invariant I gave,
(typeof x == typeof y && x == y) <=> x === y
helps keep typeof, == and === saner than otherwise. My argument builds on it by observing (independent observation) that users will expect 0L == 0UL but 0L !== 0UL. If that's true, then typeof 0L != typeof 0UL in order for the left-to-right implication direction to hold.
That means typeof 0L and typeof 0UL can' t both be "object", in spite of what
says. The simplest and clearest solution is to extend typeof so typeof 0L is "int64" and typeof 0UL is "uint64".
Programmers still use typeof heavily, much more than instanceof. The idea that it should not be extended on principle does not hold up, since IE has already done so, and more primitive relations in the language (the <=> invariant above) seem to require typeof extension, and it has
been on our agenda for value types or value objects.
So arguing "It's bad... but way better than typeof" based on a sense of smell is not enough. We need to reason from the invariant relations among operators in the language.
The simplest and clearest solution is to extend typeof so typeof 0L is "int64" and typeof 0UL is "uint64". If typeof 0L === ‘int64’, then because of it’s string nature typeof 0L !== ‘number’. Isn’t that breaking compatability?
Maybe instanceof could be extended, first as binary operator also working on string (and second as an unary operator returning the final constructor’s global name)?
var i = Int64(0L);
i instanceof ‘Int64’ === i instanceof Int64 // true i instanceof ‘Number’ === i instanceof Number // true // i instanceof ‘Object’ // true?
instanceof i === ‘Int64’ // unary returning final constructor’s name (for re-expression)
The typeof operator always issues an equal operator, so you can’t say an int64 is also a number. Isn’t it? I believe typeof should think it’s a number (like NaN or Infinity), only something more detailed knows that it is an Int64 Number. Maybe 0L is not an Object - for this I also like the post of Axel Rauschmayer, where he proposes a ValueType function. instanceof could say it’s not Object, but it is an ValueType instead. For example 0L instanceof Int64 Number ValueType and (new Int64(0L)) instanceof Int64 Number Object.
Uli metadea.de/V
-----Ursprüngliche Nachricht---
Uli Riehm wrote:
The simplest and clearest solution is to extend typeof so typeof 0L is "int64" and typeof 0UL is "uint64".
If typeof 0L === ‘int64’, then because of it’s string nature typeof 0L !== ‘number’. Isn’t that breaking compatability?
No. 0L is not yet in the language. It's a literal int64. Are you thinking of plain 0?
Maybe instanceof could be extended, first as binary operator also working on string (and second as an unary operator returning the final constructor’s global name)? var i = Int64(0L);
The name is int64, lowercase i. See strawman:value_objects
i instanceof ‘Int64’ === i instanceof Int64 // true i instanceof ‘Number’ === i instanceof Number // true // i instanceof ‘Object’ // true?
With rebased patch from bugzilla.mozilla.org/show_bug.cgi?id=749786 applied:
js> i = 0L
0L js> i instanceof int64
true js> i instanceof Number
false js> i instanceof Object
true
An int64 is not a double-precision binary floating point number.
instanceof i === ‘Int64’ // unary returning final constructor’s name (for re-expression)
Making instanceof a unary as well as binary operator is not going to fly. For one thing, the 'of' in the name is broken English here. For another, it's too easy to mess up ASI or / or a comment and end up with a binary instanceof becoming unary unintentionally.
The typeof operator always issues an equal operator, so you can’t say an int64 is also a number. Isn’t it? I believe typeof should think it’s a number (like NaN or Infinity),
No.
Number is IEEE754 double, 53 bits mantissa. Not 64 bits. The types are not related.
only something more detailed knows that it is an Int64 Number. Maybe 0L is not an Object - for this I also like the post of Axel Rauschmayer, where he proposes a ValueType function. instanceof could say it’s not Object, but it is an ValueType instead. For example 0L instanceof Int64 Number ValueType and (new Int64(0L)) instanceof Int64 Number Object.
That's nearly meaningless, though, and again fails cross-frame.
Please read the value objects proposal and consider the invariants from
-
- Value objects include int64 and uint64 instances and support the expected
-
- arithmetic operators: | ^& ==< <=<< >> >>> + - * / %, boolean test, ~,
-
- unary - and unary +.
-
-
- != and ! are not overloadable to preserve identities including
-
-
- X ? A : B<=> !X ? B : A
-
- !(X&& Y)<=> !X || !Y
-
- X != Y<=> !(X == Y)
-
-
- Similarly,> and>= are derived from< and<= as follows:
-
-
- A> B<=> B< A
-
- A>= B<=> B<= A
-
-
- We provide<= as well as< rather than derive A<= B from !(B< A) in order
-
- to allow the<= overloading to match == semantics.
-
-
- The strict equality operators, === and !==, cannot be overloaded, but they
-
- work on frozen-by-definition value objects via a structural recursive strict
-
- equality test, rather than by testing same-reference. Same-reference remains
-
- a fast-path optimization.
Value objects have strong use-cases includling int64, uint64, bignum, complex, rational. These plus the two-way typeof-==/=== implication and the 0L == 0UL sane == behavior say typeof needs more result types. One can use instanceof, obviously, since there are always constructor functions, but typeof is universal (cross-frame). This is important.
Brendan Eich wrote:
Value objects have strong use-cases includling int64, uint64, bignum, complex, rational.
And of course decimal (IEEE754r, per IBM's wishes).
On 29 September 2012 20:14, Rick Waldron <waldron.rick at gmail.com> wrote:
Offline discussion with Dave that immediately identified a deal-breaker: if typeof symbol were "string", it would break ===.
=== for strings is based on their contents === for objects is based on their identity
Well, that's clearly up to interpretation. Instead of having "identity", you can just as well view symbols as something with unique abstract "content". That is, I disagree that this alone is a deal-breaker of any kind.
But nevertheless, of course, using typeof symbol === "string" would be bad for other reasons, some of which have been brought up in this thread.
Andreas Rossberg wrote:
On 29 September 2012 20:14, Rick Waldron<waldron.rick at gmail.com> wrote:
Offline discussion with Dave that immediately identified a deal-breaker: if typeof symbol were "string", it would break ===.
=== for strings is based on their contents === for objects is based on their identity
Well, that's clearly up to interpretation. Instead of having "identity", you can just as well view symbols as something with unique abstract "content". That is, I disagree that this alone is a
+1, I wasn't able to explain this, but I also had this on my mind.
On 30 September 2012 00:08, Brendan Eich <brendan at mozilla.org> wrote:
I think this is too philosophical a discussion to result in a strong reason to risk "symbol". Just my gut-check. Other TC39ers should weigh in (Andreas R. especially).
Type "symbol" would be my preference, but it is difficult to estimate (for me) whether that involves a risk.
However, this clearly is an issue beyond symbols alone. The same problem re-arises whenever we have to add new primitive types in the future. It doesn't seem like a sustainable strategy to fake any new type ever into an object. Perhaps it is less harmful on the long run if we took the chance to clarify now that the set of strings returned by 'typeof' is not fixed, and should not be treated as such?
However, this clearly is an issue beyond symbols alone. The same problem re-arises whenever we have to add new primitive types in the future. It doesn't seem like a sustainable strategy to fake any new type ever into an object. Perhaps it is less harmful on the long run if we took the chance to clarify now that the set of strings returned by 'typeof' is not fixed, and should not be treated as such?
It would be great if there was a consistent vision as to where categorization of values should be headed: What do we need? What is categorization currently used for in practice? How can we achieve it in a future-friendly way? How can we simplify things, long term?
At the moment, things are a mess (between typeof, instanceof, [[Class]], Array.isArray, cross-frame communication, etc.). And I wouldn’t want that mess to get even worse.
ECMAScript.next is shaping up to be a nice and clean language, except for this one area.
On Mon, Oct 1, 2012 at 5:26 AM, Andreas Rossberg <rossberg at google.com>wrote:
On 30 September 2012 00:08, Brendan Eich <brendan at mozilla.org> wrote:
I think this is too philosophical a discussion to result in a strong reason to risk "symbol". Just my gut-check. Other TC39ers should weigh in (Andreas R. especially).
Type "symbol" would be my preference, but it is difficult to estimate (for me) whether that involves a risk.
However, this clearly is an issue beyond symbols alone. The same problem re-arises whenever we have to add new primitive types in the future. It doesn't seem like a sustainable strategy to fake any new type ever into an object. Perhaps it is less harmful on the long run if we took the chance to clarify now that the set of strings returned by 'typeof' is not fixed, and should not be treated as such?
+1 for "symbol", after reading through past concerns about adding new entries to typeof operator results, I'm not convinced that adding something completely new would have any negative side-effects. I'll be the first to admit that there are probably edge cases that I may have missed or didn't find, but I think the real risk is in piling new things on to existing typeof results when they questionably don't belong.
On Mon, Oct 1, 2012 at 12:00 PM, Rick Waldron <waldron.rick at gmail.com>wrote:
On Mon, Oct 1, 2012 at 5:26 AM, Andreas Rossberg <rossberg at google.com>wrote:
On 30 September 2012 00:08, Brendan Eich <brendan at mozilla.org> wrote:
I think this is too philosophical a discussion to result in a strong reason to risk "symbol". Just my gut-check. Other TC39ers should weigh in (Andreas R. especially).
Type "symbol" would be my preference, but it is difficult to estimate (for me) whether that involves a risk.
However, this clearly is an issue beyond symbols alone. The same problem re-arises whenever we have to add new primitive types in the future. It doesn't seem like a sustainable strategy to fake any new type ever into an object. Perhaps it is less harmful on the long run if we took the chance to clarify now that the set of strings returned by 'typeof' is not fixed, and should not be treated as such?
+1 for "symbol", after reading through past concerns about adding new entries to typeof operator results, I'm not convinced that adding something completely new would have any negative side-effects. I'll be the first to admit that there are probably edge cases that I may have missed or didn't find, but I think the real risk is in piling new things on to existing typeof results when they questionably don't belong.
To try and make clear the risk that Brendan's alluding to think of it this way: how many times have you written code that type-checks and assumes the range of typeof is fixed? I've written code like this more times than I can count:
if (attr == null) // null or undefined
else if (typeof attr == 'string') // string
else if (typeof attr == 'number') // number
else if (typeof attr == 'object') // whoops...
// handle arrays, objects, dates, regex, etc.
For code that falls through to 'object' it's possible the handler is sufficiently generic, but changing the range of typeof changes assumptions and will silently break old code, and for the same reason typeof 'null' was nixed. This is a subtly backward-hostile change that doesn't fix anything. It just introduces another barrier to es-next migration.
I'm convinced that typeof is a lost cause, but FWIW I believe symbols themselves give us a way out of this mess.
On Mon, Oct 1, 2012 at 9:23 AM, Dean Landolt <dean at deanlandolt.com> wrote:
On Mon, Oct 1, 2012 at 12:00 PM, Rick Waldron <waldron.rick at gmail.com>wrote:
On Mon, Oct 1, 2012 at 5:26 AM, Andreas Rossberg <rossberg at google.com>wrote:
On 30 September 2012 00:08, Brendan Eich <brendan at mozilla.org> wrote:
I think this is too philosophical a discussion to result in a strong reason to risk "symbol". Just my gut-check. Other TC39ers should weigh in (Andreas R. especially).
Type "symbol" would be my preference, but it is difficult to estimate (for me) whether that involves a risk.
However, this clearly is an issue beyond symbols alone. The same problem re-arises whenever we have to add new primitive types in the future. It doesn't seem like a sustainable strategy to fake any new type ever into an object. Perhaps it is less harmful on the long run if we took the chance to clarify now that the set of strings returned by 'typeof' is not fixed, and should not be treated as such?
+1 for "symbol", after reading through past concerns about adding new entries to typeof operator results, I'm not convinced that adding something completely new would have any negative side-effects. I'll be the first to admit that there are probably edge cases that I may have missed or didn't find, but I think the real risk is in piling new things on to existing typeof results when they questionably don't belong.
To try and make clear the risk that Brendan's alluding to think of it this way: how many times have you written code that type-checks and assumes the range of typeof is fixed? I've written code like this more times than I can count:
if (attr == null) // null or undefined else if (typeof attr == 'string') // string else if (typeof attr == 'number') // number else if (typeof attr == 'object') // whoops... // handle arrays, objects, dates, regex, etc.
The example you gave wouldn't be "symbol aware" anywhere else either... but let's say that this is part of some library code that accepts arguments from user code and a symbol is passed in - none of those conditions would be met (if typeof "symbol") and therefore nothing would happen. I don't think this is strong enough to block the possibility of a new typeof result.
For code that falls through to 'object' it's possible the handler is sufficiently generic, but changing the range of typeof changes assumptions and will silently break old code, and for the same reason typeof 'null' was nixed.
Adding a new result that accompanies a new language feature is not the same as changing something with 17 years worth of extant code.
This is a subtly backward-hostile change that doesn't fix anything. It just introduces another barrier to es-next migration.
It's only "backwards-hostile" if user code intentionally creates hostile execution paths. Any comparison using "symbol" simply won't evaluate to true in older implementations... but then older implementations won't have symbols anyway.
I'm convinced that typeof is a lost cause, but FWIW I believe symbols themselves give us a way out of this mess.
I don't actually see what symbols themselves will do to be so heroic
On Mon, Oct 1, 2012 at 12:41 PM, Rick Waldron <waldron.rick at gmail.com>wrote:
On Mon, Oct 1, 2012 at 9:23 AM, Dean Landolt <dean at deanlandolt.com> wrote:
On Mon, Oct 1, 2012 at 12:00 PM, Rick Waldron <waldron.rick at gmail.com>wrote:
On Mon, Oct 1, 2012 at 5:26 AM, Andreas Rossberg <rossberg at google.com>wrote:
On 30 September 2012 00:08, Brendan Eich <brendan at mozilla.org> wrote:
I think this is too philosophical a discussion to result in a strong reason to risk "symbol". Just my gut-check. Other TC39ers should weigh in (Andreas R. especially).
Type "symbol" would be my preference, but it is difficult to estimate (for me) whether that involves a risk.
However, this clearly is an issue beyond symbols alone. The same problem re-arises whenever we have to add new primitive types in the future. It doesn't seem like a sustainable strategy to fake any new type ever into an object. Perhaps it is less harmful on the long run if we took the chance to clarify now that the set of strings returned by 'typeof' is not fixed, and should not be treated as such?
+1 for "symbol", after reading through past concerns about adding new entries to typeof operator results, I'm not convinced that adding something completely new would have any negative side-effects. I'll be the first to admit that there are probably edge cases that I may have missed or didn't find, but I think the real risk is in piling new things on to existing typeof results when they questionably don't belong.
To try and make clear the risk that Brendan's alluding to think of it this way: how many times have you written code that type-checks and assumes the range of typeof is fixed? I've written code like this more times than I can count:
if (attr == null) // null or undefined else if (typeof attr == 'string') // string else if (typeof attr == 'number') // number else if (typeof attr == 'object') // whoops... // handle arrays, objects, dates, regex, etc.
The example you gave wouldn't be "symbol aware" anywhere else either...
Sorry, I somehow clipped off my else clause that demonstrated the problem (assumed function). I also missed 'boolean'.
but let's say that this is part of some library code that accepts arguments from user code and a symbol is passed in - none of those conditions would be met (if typeof "symbol") and therefore nothing would happen.
This is where we disagree. Something bad will almost certainly happen if your "else" clause isn't "object". I bet an awful lot of code in the wild assumes the range of typeof to be invariant. I'm not claiming the range of typeof is codified as a language invariant (I haven't checked the spec), just that there is sure to be code in the wild that assumes this and will be tripped up by a contravariant change. That's why I referred to it as backward hostile, not backward-incompatible.
I don't think this is strong enough to block the possibility of a new typeof result.
Fair enough. But is there any value in a new typeof result? I surely can't see any. It's broken beyond repair -- I don't see the use in breaking more code trying to salvage it :P
For code that falls through to 'object' it's possible the handler is sufficiently generic, but changing the range of typeof changes assumptions and will silently break old code, and for the same reason typeof 'null' was nixed.
Adding a new result that accompanies a new language feature is not the same as changing something with 17 years worth of extant code.
If you consider the range of typeof to be a language invariant it's the same class of problem.
This is a subtly backward-hostile change that doesn't fix anything. It just introduces another barrier to es-next migration.
It's only "backwards-hostile" if user code intentionally creates hostile execution paths. Any comparison using "symbol" simply won't evaluate to true in older implementations... but then older implementations won't have symbols anyway.
Any fallthrough that assumes complete coverage of the typeof range is a hostile path. I believe these are common enough to be a concern. The fact that IE already extends the range of typeof probably could mean less cause for concern, but this is still a real problem. I know I wrote an awful lot of code assuming the range of typeof to be a language invariant -- I doubt I'm alone.
I'm convinced that typeof is a lost cause, but FWIW I believe symbols themselves give us a way out of this mess.
I don't actually see what symbols themselves will do to be so heroic
I should have been more clear -- symbols give us protocols. For instance, it'll get a whole lot easier to test for "array-like" when all we care about is whether something is iterable. And how do we tell that? The language gives us this perfect, intensional key. This general pattern can be extended for custom protocols. I think that's pretty heroic :)
Andreas Rossberg wrote:
On 30 September 2012 00:08, Brendan Eich<brendan at mozilla.org> wrote:
I think this is too philosophical a discussion to result in a strong reason
to risk "symbol". Just my gut-check. Other TC39ers should weigh in (Andreas
R. especially).
Type "symbol" would be my preference, but it is difficult to estimate (for me) whether that involves a risk.
However, this clearly is an issue beyond symbols alone. The same problem re-arises whenever we have to add new primitive types in the future. It doesn't seem like a sustainable strategy to fake any new type ever into an object. Perhaps it is less harmful on the long run if we took the chance to clarify now that the set of strings returned by 'typeof' is not fixed, and should not be treated as such?
I could go for that (see my "int64" and "uint64" argument).
And as noted, IE has softened up the developers, or so I hear.
Someone who knows more should weigh in. I even heard that in IE JScript (or possibly even IE9/10 Chakra -- "JavaScript"), typeof can return "unknown"! True?
It's a mistake to mix up the two-level distinction in JS, though. Backward compatibility and the ==/=== invariant require typeof to classify a certain way that cannot capture instanceof. You can't fold the two into one.
My position remains that we should leave instanceof alone and extend typeof where the relations we want to preserve require it.
Brendan Eich wrote:
It's a mistake to mix up the two-level distinction in JS, though. Backward compatibility and the ==/=== invariant require typeof to classify a certain way that cannot capture instanceof. You can't fold the two into one.
As I read it (and as I see it), there was not a call for folding the two into one. I see it as a call to "institutionalize" the de-facto status quo, where typeof distinguishes between objects ("object" and "function") and primitives/atoms (everything else), while primitives/atoms are 2nd-level-distinguished among themselves by the actual typeof value (objects do not, they use instanceof or other means to do it).
If this is the case, it implicitly means that if new type of primitive is added to the language, it gets its typeof tag; but the realm of true objects is not harmed in any way.
Herby Vojčík wrote:
Brendan Eich wrote:
It's a mistake to mix up the two-level distinction in JS, though. Backward compatibility and the ==/=== invariant require typeof to classify a certain way that cannot capture instanceof. You can't fold the two into one.
As I read it (and as I see it), there was not a call for folding the two into one. I see it as a call to "institutionalize" the de-facto status quo, where typeof distinguishes between objects ("object" and "function") and primitives/atoms (everything else), while primitives/atoms are 2nd-level-distinguished among themselves by the actual typeof value (objects do not, they use instanceof or other means to do it).
Axel wrote
"At the moment, things are a mess (between typeof, instanceof, [[Class]], Array.isArray, cross-frame communication, etc.). And I wouldn’t want that mess to get even worse."
and he is right, but the complaints there come from instanceof failing cross-frame.
typeof works cross-frame.
But this does not mean extending typeof to distinguish within non-function objects.
If this is the case, it implicitly means that if new type of primitive is added to the language, it gets its typeof tag; but the realm of true objects is not harmed in any way.
We agree on this, but I think Axel is right to lament the cross-frame problem with instanceof, which begat Array.isArray.
Just to repeat, and I'm not sure where Axel stands on this: extending typeof does not make this problem worse. But I do not see a way to extend typeof to solve the cross-frame object classification problem.
Le 01/10/2012 21:42, Brendan Eich a écrit :
Andreas Rossberg wrote:
On 30 September 2012 00:08, Brendan Eich<brendan at mozilla.org> wrote:
I think this is too philosophical a discussion to result in a strong reason to risk "symbol". Just my gut-check. Other TC39ers should weigh in (Andreas R. especially).
Type "symbol" would be my preference, but it is difficult to estimate (for me) whether that involves a risk.
However, this clearly is an issue beyond symbols alone. The same problem re-arises whenever we have to add new primitive types in the future. It doesn't seem like a sustainable strategy to fake any new type ever into an object. Perhaps it is less harmful on the long run if we took the chance to clarify now that the set of strings returned by 'typeof' is not fixed, and should not be treated as such?
I could go for that (see my "int64" and "uint64" argument).
And as noted, IE has softened up the developers, or so I hear.
Someone who knows more should weigh in. I even heard that in IE JScript (or possibly even IE9/10 Chakra -- "JavaScript"), typeof can return "unknown"! True?
Try "typeof document.createElement('div').offsetParent" on IE6-8. I can't verify because I'm not Ubuntu right now, but if I recall it will give you "unknown". If it works, credit where it's due, John-David Dalton shared this to me a while ago. If it doesn't work, sorry for the noise. If I had to guess, I'd say it's been fixed in IE9, but I'm interested if someone can test.
On Mon, Oct 1, 2012 at 4:23 PM, David Bruant <bruant.d at gmail.com> wrote:
Le 01/10/2012 21:42, Brendan Eich a écrit :
Andreas Rossberg wrote:
On 30 September 2012 00:08, Brendan Eich<brendan at mozilla.org> wrote:
I think this is too philosophical a discussion to result in a strong reason to risk "symbol". Just my gut-check. Other TC39ers should weigh in (Andreas R. especially).
Type "symbol" would be my preference, but it is difficult to estimate (for me) whether that involves a risk.
However, this clearly is an issue beyond symbols alone. The same problem re-arises whenever we have to add new primitive types in the future. It doesn't seem like a sustainable strategy to fake any new type ever into an object. Perhaps it is less harmful on the long run if we took the chance to clarify now that the set of strings returned by 'typeof' is not fixed, and should not be treated as such?
I could go for that (see my "int64" and "uint64" argument).
And as noted, IE has softened up the developers, or so I hear.
Someone who knows more should weigh in. I even heard that in IE JScript (or possibly even IE9/10 Chakra -- "JavaScript"), typeof can return "unknown"! True? Try "typeof document.createElement('div').offsetParent" on IE6-8. I can't verify because I'm not Ubuntu right now, but if I recall it will give you "unknown". If it works, credit where it's due, John-David Dalton shared this to me a while ago. If it doesn't work, sorry for the noise. If I had to guess, I'd say it's been fixed in IE9, but I'm interested if someone can test.
I don't need to run it to confirm. It definitely "unknown" ;)
From: es-discuss-bounces at mozilla.org [es-discuss-bounces at mozilla.org] on behalf of David Bruant [bruant.d at gmail.com] Sent: Monday, October 01, 2012 16:23 To: Brendan Eich Cc: es-discuss Subject: Re: typeof symbol (Was: Sept 19 TC39 Meeting Notes)
Try "typeof document.createElement('div').offsetParent" on IE6-8. I can't verify because I'm not Ubuntu right now, but if I recall it will give you "unknown". If it works, credit where it's due, John-David Dalton shared this to me a while ago. If it doesn't work, sorry for the noise. If I had to guess, I'd say it's been fixed in IE9, but I'm interested if someone can test.
Yeah, according to IE10 and its compatibility modes at least, IE7 and IE8 give "unknown" while IE9 and IE10 give "object".
It's a mistake to mix up the two-level distinction in JS, though. Backward compatibility and the ==/=== invariant require typeof to classify a certain way that cannot capture instanceof. You can't fold the two into one.
Internally, probably not, because primitives are fundamentally different. But what the user is seeing is different. I’ve used JavaScript for years, without knowing about the difference. And one often reads “everything is an object in JavaScript” on the web, because the illusion is really quite well maintained (except for typeof vs. instanceof).
But “a better instanceof” is something that can be prototyped as a library function. I’ll do so and will also try to figure out what the actual use cases for typeof/instanceof are – this kind of categorization is indeed a bit of an anti-pattern (I think Allen pointed that out recently).
As I read it (and as I see it), there was not a call for folding the two into one. I see it as a call to "institutionalize" the de-facto status quo, where typeof distinguishes between objects ("object" and "function") and primitives/atoms (everything else), while primitives/atoms are 2nd-level-distinguished among themselves by the actual typeof value (objects do not, they use instanceof or other means to do it).
That would be nice as a complementary measure. Especially "null" would be great, but it seems like a risky change. Having both "object" and "function" is something that’s unfortunate, but unfixable.
Axel wrote
"At the moment, things are a mess (between typeof, instanceof, [[Class]], Array.isArray, cross-frame communication, etc.). And I wouldn’t want that mess to get even worse."
and he is right, but the complaints there come from instanceof failing cross-frame.
Right, sorry for conflating two issues. My main point was: any kind of simplification of the current situation helps (even typeof o === "null" which, OTOH, might not be worth the risk).
Regarding cross-frame: Many explanations on the web of determining whether a value is an array sound like this is an impossible task (ignoring Array.isArray()) and that’s a shame. Alas, I’m not sure how one could do better here, it’s really a tricky problem. postMessage seems like a partial solution.
Just to repeat, and I'm not sure where Axel stands on this: extending typeof does not make this problem worse. But I do not see a way to extend typeof to solve the cross-frame object classification problem.
I agree. typeof should (at most) be slightly updated to keep up with changes and to become less quirky.
Axel
Axel Rauschmayer wrote:
Right, sorry for conflating two issues. My main point was: any kind of simplification of the current situation helps (even typeof o === "null" which, OTOH, might not be worth the risk).
We can't change typeof null === "null". V8 tried and it broke the web, and 1JS means we do not want typeof changing rules under module {...}
My main point was: any kind of simplification of the current situation helps (even typeof o === "null" which, OTOH, might not be worth the risk).
We can't change typeof null === "null". V8 tried and it broke the web, and 1JS means we do not want typeof changing rules under module {...} -- that's a gratuitous refactoring hazard.
typeof (function(){}) == "function" && typeof null == "object" && typeof {} == "object" -- just grieve and accept! I have :-P. Doesn't mean typeof is not useful and indeed widely used, and important for the ==/=== two-way implication. Other type tests would work for that implication, but typeof is the one in the language.
I agree, sorry for not having been clearer – that’s what I meant by “ might not be worth the risk”. But it seems to have come up again as a possibility in this thread.
Regarding cross-frame: Many explanations on the web of determining whether a value is an array sound like this is an impossible task (ignoring Array.isArray()) and that’s a shame. Alas, I’m not sure how one could do better here, it’s really a tricky problem. postMessage seems like a partial solution.
Or Object.prototype.toString.call(x).slice(8, -1) === "Array"? Not iron-clad but prior to Array.isArray, nothing is.
Yes, but yet another special case: “use typeof (along with === and !==), except where you have to use instanceof, except where you have to access [[Class]] in a non-obvious manner”.
I’m not complaining, merely suggesting that there must be a better way. But I’ll offer something concrete by writing up a few thoughts.
Axel Rauschmayer wrote:
My main point was: any kind of simplification of the current situation helps (even typeof o === "null" which, OTOH, might not be worth the risk).
We can't change typeof null === "null". V8 tried and it broke the web, and 1JS means we do not want typeof changing rules under module {...} -- that's a gratuitous refactoring hazard.
typeof (function(){}) == "function" && typeof null == "object" && typeof {} == "object" -- just grieve and accept! I have :-P. Doesn't mean typeof is not useful and indeed widely used, and important for the ==/=== two-way implication. Other type tests would work for that implication, but typeof is the one in the language.
I agree, sorry for not having been clearer – that’s what I meant by “ might not be worth the risk”. But it seems to have come up again as a possibility in this thread.
Not that I saw. Changing typeof result for existing inputs is off the table with 1JS.
Regarding cross-frame: Many explanations on the web of determining whether a value is an array sound like this is an impossible task (ignoring Array.isArray()) and that’s a shame. Alas, I’m not sure how one could do better here, it’s really a tricky problem. postMessage seems like a partial solution.
Or Object.prototype.toString.call(x).slice(8, -1) === "Array"? Not iron-clad but prior to Array.isArray, nothing is.
Yes, but yet another special case: “use typeof (along with === and !==), except where you have to use instanceof, except where you have to access [[Class]] in a non-obvious manner”.
I’m not complaining, merely suggesting that there must be a better way. But I’ll offer something concrete by writing up a few thoughts.
Definitely can have better library solutions, including something in the standard library when "baked".
Let a thousand flowers bloom? (That was not auspicious for most flower growers, but nm.) The problem then becomes picking the prettiest flower, especially if the various users do not all agree.
Definitely can have better library solutions, including something in the standard library when "baked".
Let a thousand flowers bloom? (That was not auspicious for most flower growers, but nm.) The problem then becomes picking the prettiest flower, especially if the various users do not all agree.
Makes sense. And gives us something concrete to talk about.
It also engenders curiosity of what JavaScript prison looks like.
On 1 October 2012 21:17, Dean Landolt <dean at deanlandolt.com> wrote:
Fair enough. But is there any value in a new typeof result? I surely can't see any. It's broken beyond repair -- I don't see the use in breaking more code trying to salvage it :P
There isn't much value in a new typeof result as such. But it avoids the (potentially significant) cost of requiring that every new primitive type ever introduced behaves like an object.
2012/9/29 Andreas Rossberg <rossberg at google.com>
I'm not against thinking of symbols as an entirely new "class" of values. I was mostly arguing against the idea of having typeof symbol be "string". If there are good reasons for symbols not to get their own typeof type, I just think "object" would be more reasonable than "string".