Re: Implicit coercion of Symbols
From: Domenic Denicola d...@domenic.me To: Rick Waldron waldron.r...@gmail.com, es-discuss es-discuss@mozilla.org Cc: Date: Mon, 12 Jan 2015 18:02:17 + Subject: RE: Implicit coercion of Symbols I re-read through this whole thread and realized nobody brought up the fact that this *specific* change, of making `String(symbol)` work while `symbol+` throws, was discussed and agreed upon previously: - https://esdiscuss.org/topic/string-symbol - https://github.com/tc39/tc39-notes/blob/master/es6/2014-09/sept-23.md#41-spec-status-report I realize people are presumably having second thoughts, but I thought it'd be worth linking to the previous thread for anyone who hasn't seen it and thinks this is a new debate. Good catch. I wouldn't have been surprised if nobody even thought of it until now (in this discussion, anyways). -- Isiah Meadows ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Implicit coercion of Symbols
Indeed, in my first reply on-thread, I wrote This is exactly the reason. to acknowledge existing consensus. Thanks for linking! /be Domenic Denicola wrote: I re-read through this whole thread and realized nobody brought up the fact that this*specific* change, of making `String(symbol)` work while `symbol+` throws, was discussed and agreed upon previously: -https://esdiscuss.org/topic/string-symbol -https://github.com/tc39/tc39-notes/blob/master/es6/2014-09/sept-23.md#41-spec-status-report I realize people are presumably having second thoughts, but I thought it'd be worth linking to the previous thread for anyone who hasn't seen it and thinks this is a new debate. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: {Spam?} Re: Implicit coercion of Symbols
Andrea Giammarchi wrote: A generic description-aware `Reflect.describe(genericObject)`like approach seems way more useful for logging annd debugging purpose than a footgun in the wild. Good idea, should find an ES7 champion. If we had this, I think we could have made String(sym) throw, and perhaps would have. Should have :-P. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Implicit coercion of Symbols
Le 4 janv. 2015 à 03:18, Rick Waldron waldron.r...@gmail.com a écrit : On Sat Jan 03 2015 at 8:25:40 PM Brendan Eich bren...@mozilla.org wrote: Rick Waldron wrote: That example above is pretty compelling for throw always consistency. With a new Reflect.* API for converting a symbol to its diagnostic/debugging string? If you agree, please file a bugs.ecmascript.org ticket. https://bugs.ecmascript.org/show_bug.cgi?id=3509 I think that it is asking for the wrong consistency. There is another consistency to be wanted, namely: String(sym) === sym.toString() (assuming that `Symbol.prototype.toString` isn't sabotaged by user code, of course). Indeed: * `String(sym)` and `sym.toString()` are *explicit* coercions to string; while * `sym + ` triggers an *implicit* coercion to string (in that very case, preceded by a coercion to primitive, but it's not the subject). Now, it will be argued that it would be a precedent to make such a distinction between implicit and explicit coercion, for, until ES5, there is none. But, precisely, pervasive implicit coercion is often thought to be a mistake in the design of JavaScript (it hides bugs), while coercion in general is indeed useful (e.g., for debugging purpose, as pointed Alex in this thread). Now, as we are evolving the language, it is good to limit the scope of the bad implicit coercion behaviour (such as the abstract operation `ToString()` of the spec), but to consolidate the functionality of the existing explicit coercion functions (such as `String()`). If there is a need to directly expose the implicit coercion to string operation to user code, `Reflect.toString()` is a natural fit for that, together with `Reflect.toBoolean()`, `Reflect.toPropertyKey()`, `Reflect.toPrimitive(_, hint)`, etc. —Claude ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Implicit coercion of Symbols
Alex Kocharin wrote: My point is: concatenating Symbols with other strings have legitimate uses. Name one. I did name one in another message. Logging. That's a use-case for some way (could be concatenation, but as noted the downside risk is huge; could be a new Reflect method) to convert symbol to string. Explicit is better than implicit. Saying Logging does not say allow implicit symbol to string conversion. I agree that String(sym) working where ''+sym throws is funky (my word in this thread). We could make both throw, with a Reflect.symbolToString or whatever it might be called. ES6 is about out of time, this may not fly, but if it is possible it has to be done quickly. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Implicit coercion of Symbols
Alex, like I've said: `log({__proto__:null})` and welcome crashes of the server, if that's a real concern in this form. Is it that wrong to assume that if `console.log({__proto__:null})` is capable of handling non Objects and print a meaningful output, so should any other logger implemented on user-land? 'cause logging a part there's still no case where implicit or explicit Symbol cast makes any sense. It's like `object['undefined']` where `undefined` is implicitly created by some missed property which has been somehow problematic for long time. A generic description-aware `Reflect.describe(genericObject)`like approach seems way more useful for logging annd debugging purpose than a footgun in the wild. Regards On Sun, Jan 4, 2015 at 3:41 AM, Alex Kocharin a...@kocharin.ru wrote: 04.01.2015, 04:58, Brendan Eich bren...@mozilla.org: Alex Kocharin wrote: The code will be incorrect if you pass any regular object in there. Why should symbol be any different? For me, its throwing behavior is just another thing that could crash server-side node.js process for no good reason. No good reason? Wrong. Just because bugs pass without exception doesn't mean we must continue the tradition. It isn't always a bug. People could cast something to a string for debugging purposes like this: ``` function log(anything) { process.stdout.write(new Date().toJSON() + ' - ' + anything + '\n') } ``` Right now it'll never throw. Well, unless you override `.toString()` to throw, which I've never seen to be done intentionally. With throwing Symbols we'll have innocuous-looking code which will cause an exception. And since javascript developers don't usually have a history of using throw..catch everywhere (some even avoid it for performance reasons), the consequences could be quite dire. Thus, every single code snippet that use type casting will have to either be wrapped with try..catch or checked for `symbol` explicitly. Maybe we'll write libraries called castAnythingToStringSafely because of that (like json-stringify-safe is created because JSON.stringify throws). And it'll surely make things worse for the beginners who don't know language well enough to remember to add those workarounds everywhere. So yes, I think that the existence of the errors you mentioned isn't a good reason to throw. There is no way for the interpreter to check developer intentions, and the casting can be used for good. Also, if you want to prevent mistakes like `object['blah' + symbol]`, linters could be changed to forbid/warn about concatenation inside property names. It's their job to warn about suspicious behavior, javascript spec should stay as simple as possible imho. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Implicit coercion of Symbols
Claude Pache wrote: Now, it will be argued that it would be a precedent to make such a distinction between implicit and explicit coercion, for, until ES5, there is none. Kind of there all along, as noted up-thread: js o = {valueOf(){return 42}, toString(){return 'haha'}} ({valueOf:function valueOf(){return 42}, toString:function toString(){return 'haha'}}) js String(o) haha js ''+o 42 But I take your point. But, precisely, pervasive implicit coercion is often thought to be a mistake in the design of JavaScript (it hides bugs), while coercion in general is indeed useful (e.g., for debugging purpose, as pointed Alex in this thread). *Explicit* coercion in general is useful. What's explicit? It could be console.log is an explicit-enough gesture. It does more than just ToString on its parameters today, IINM (at least in some browsers). Now, as we are evolving the language, it is good to limit the scope of the bad implicit coercion behaviour (such as the abstract operation `ToString()` of the spec), but to consolidate the functionality of the existing explicit coercion functions (such as `String()`). Yes, this is the rationale for ES6's symbol handling today. If there is a need to directly expose the implicit coercion to string operation to user code, `Reflect.toString()` is a natural fit for that, together with `Reflect.toBoolean()`, `Reflect.toPropertyKey()`, `Reflect.toPrimitive(_, hint)`, etc. Yup; ES7 fodder at this stage. I think it's very unlikely anyone will try to patch ES6 over the trade-offs among consistencies that this thread has illuminated. Thanks, /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Implicit coercion of Symbols
Forgot to retitle it. On Jan 3, 2015 9:44 PM, Isiah Meadows impinb...@gmail.com wrote: From: Axel Rauschmayer a...@rauschma.de To: bren...@mozilla.org Cc: es-discuss list es-discuss@mozilla.org Date: Sun, 4 Jan 2015 03:17:54 +0100 Subject: Re: Implicit coercion of Symbols Does it have to be a Reflect.* method? It could be `Symbol.prototype.getDescription()` or a getter. On 04 Jan 2015, at 02:25, Brendan Eich bren...@mozilla.org wrote: Rick Waldron wrote: That example above is pretty compelling for throw always consistency. With a new Reflect.* API for converting a symbol to its diagnostic/debugging string? If you agree, please file a bugs.ecmascript.org ticket. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- Dr. Axel Rauschmayer a...@rauschma.de rauschma.de A good name for such a getter would be, IMO, `Symbol.prototype.description`. It would also seem to fit with some other common JS idioms, such as `Array.prototype.length`, etc. It also feels clearer and cleaner as a getter than an instance method or function. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Implicit coercion of Symbols
On Sat Jan 03 2015 at 3:56:38 PM Brendan Eich bren...@mozilla.org wrote: Axel Rauschmayer wrote: On 03 Jan 2015, at 19:52, Brendan Eich bren...@mozilla.org mailto:bren...@mozilla.org wrote: None of the objects in the examples bz cited are Arrays -- what did you mean? When I though of `+` being used inside square brackets, I only thought of strings, not of numbers (first example). In the first example, `this` is at least array-like. Otherwise, `slice` wouldn’t work. Sure, but you wrote Arrays, not array-likes. Also bracketing for computed property access works with any object, not just array-likes. Sorry to be nit-picky but precision required here ;-). Right, but regardless of how the potential footgun is loaded, the exception is the divergence. That specifically is what I want us to look at—is this the right thing to do here? Currently, user code can do things like this: var a = {}; //... sometime later... a[o + _idfoobarwhatever] = my important stuff; And even if `o` isn't a what the author expected, execution proceeds. I still think that the exception is a good path forward, but I may not be right about that. The exception... A. Requires user code to be more thoroughly tested—which is a good thing, but inexperienced programmers won't think so. B. Diverges from the well known implicit coercion behaviors that the language has had for 20 years (@Brendan: sorry for the reminder ;). This is arguably both a good thing and a bad thing (C, D, E, F) C. Prevents user code from doing the wrong thing (assuming that A is adhered to). D. Produces a surprising behavior (in comparison to all other implicit coercion operations) E. W/r to A and C, most code will need some kind of guard, just to avoid the exception, ie. either try/catch or `if (typeof s !== symbol) ...` F. Not directly related, but querySelectorAll(...) throws if the selector is invalid, which is widely considered a poor design choice for that API. This is something that _all_ DOM-centric libraries paper over, because authors would prefer that an invalid selector simply produce the equivalent of no found elements, than throwing an exception. Subjectively: I think it's nice in theory, but bad in practice. Rick ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Implicit coercion of Symbols
On 03 Jan 2015, at 19:52, Brendan Eich bren...@mozilla.org wrote: None of the objects in the examples bz cited are Arrays -- what did you mean? When I though of `+` being used inside square brackets, I only thought of strings, not of numbers (first example). In the first example, `this` is at least array-like. Otherwise, `slice` wouldn’t work. Axel Rauschmayer wrote: Arrays are a good point, this is where I’d think accidental coercions are most likely. The other use case is object-as-dictionary, which will slowly be replaced by `Object.create(null)` (no need to escape in ES6+) and `Map`. I don’t feel strongly either way, I just feel that the added spec complexity is not ideal. Especially ToBoolean() not throwing an exception, while ToString() and ToNumber() do. On 03 Jan 2015, at 04:02, Boris Zbarsky bzbar...@mit.edu mailto:bzbar...@mit.edu wrote: On 1/2/15 9:40 PM, Axel Rauschmayer wrote: Can you give an example? get: function( num ) { return num != null ? // Return just the one element from the set ( num 0 ? this[ num + this.length ] : this[ num ] ) : // Return all the elements in a clean array slice.call( this ); }, That's from jQuery 2.1.3. And from the same place: function cache( key, value ) { // Use (key + ) to avoid collision with native prototype properties (see Issue #157) if ( keys.push( key + ) Expr.cacheLength ) { // Only keep the most recent entries delete cache[ keys.shift() ]; } return (cache[ key + ] = value); } -- Dr. Axel Rauschmayer a...@rauschma.de rauschma.de ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Implicit coercion of Symbols
Arrays are a good point, this is where I’d think accidental coercions are most likely. The other use case is object-as-dictionary, which will slowly be replaced by `Object.create(null)` (no need to escape in ES6+) and `Map`. I don’t feel strongly either way, I just feel that the added spec complexity is not ideal. Especially ToBoolean() not throwing an exception, while ToString() and ToNumber() do. On 03 Jan 2015, at 04:02, Boris Zbarsky bzbar...@mit.edu wrote: On 1/2/15 9:40 PM, Axel Rauschmayer wrote: Can you give an example? get: function( num ) { return num != null ? // Return just the one element from the set ( num 0 ? this[ num + this.length ] : this[ num ] ) : // Return all the elements in a clean array slice.call( this ); }, That's from jQuery 2.1.3. And from the same place: function cache( key, value ) { // Use (key + ) to avoid collision with native prototype properties (see Issue #157) if ( keys.push( key + ) Expr.cacheLength ) { // Only keep the most recent entries delete cache[ keys.shift() ]; } return (cache[ key + ] = value); } That's after looking through about 1/10 of the library. I'll bet there are more. I'll also bet this sort of thing appears in every single major library out there. -Boris -- Dr. Axel Rauschmayer a...@rauschma.de rauschma.de ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Implicit coercion of Symbols
Axel Rauschmayer wrote: On 03 Jan 2015, at 19:52, Brendan Eich bren...@mozilla.org mailto:bren...@mozilla.org wrote: None of the objects in the examples bz cited are Arrays -- what did you mean? When I though of `+` being used inside square brackets, I only thought of strings, not of numbers (first example). In the first example, `this` is at least array-like. Otherwise, `slice` wouldn’t work. Sure, but you wrote Arrays, not array-likes. Also bracketing for computed property access works with any object, not just array-likes. Sorry to be nit-picky but precision required here ;-). /be Axel Rauschmayer wrote: Arrays are a good point, this is where I’d think accidental coercions are most likely. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Implicit coercion of Symbols
Rick Waldron wrote: Subjectively: I think it's nice in theory, but bad in practice. Compared to what? Converting a symbol to asilent-but-deadly string? I thought you were gonna raise the other way to restore consistency: make String(sym) throw too. Then we'd need a new Reflect op to get a string from a symbol. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Implicit coercion of Symbols
On Sat Jan 03 2015 at 5:56:33 PM Brendan Eich bren...@mozilla.org wrote: Rick Waldron wrote: Subjectively: I think it's nice in theory, but bad in practice. Compared to what? Converting a symbol to asilent-but-deadly string? Sorry, that was poorly delivered—I was editorializing on the benefit of exception vs consistency vs expectation. I still agree that silent-but-deadly string issue is problematic, but it seems like an edge case for Symbols. Yes, plenty of code concatenates strings and/or numbers to make an object key or an array index; but just like [object Foo]42 or undefined42, Symbol(description)42 is a obvious mistake and has the same bad outcome as the preceding two. The exception sucks and silent strings suck. I don't know which sucks less ;) Rick ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Implicit coercion of Symbols
Agreed with Brendan, and I've thought the same. It's been also years we have problems using unknonw objects in the wild, i.e. ```js var n = {__proto__:null}; var s = String(n); // error, No default value var s = '' + n; // error, No default value ``` Same if used as [property accessor] so I am not sure why `String(o)` when `o` is `Symbol` should not throw. I'd expect it to throw all the time and let developers be a bit more careful on their explicit or implicit casts. The `toString` and `valueOf` are great examples that could compromise a lot of real-world code. Being `Symbols` new we should probably/hopefully get them in the right way. I feel like throwing either cases is the right way. Just my thoughts, Best Regards On Sat, Jan 3, 2015 at 11:56 PM, Brendan Eich bren...@mozilla.org wrote: Rick Waldron wrote: Subjectively: I think it's nice in theory, but bad in practice. Compared to what? Converting a symbol to asilent-but-deadly string? I thought you were gonna raise the other way to restore consistency: make String(sym) throw too. Then we'd need a new Reflect op to get a string from a symbol. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Implicit coercion of Symbols
On Sat Jan 03 2015 at 6:30:43 PM Andrea Giammarchi andrea.giammar...@gmail.com wrote: Agreed with Brendan, and I've thought the same. It's been also years we have problems using unknonw objects in the wild, i.e. ```js var n = {__proto__:null}; var s = String(n); // error, No default value var s = '' + n; // error, No default value ``` Same if used as [property accessor] so I am not sure why `String(o)` when `o` is `Symbol` should not throw. I'd expect it to throw all the time and let developers be a bit more careful on their explicit or implicit casts. The `toString` and `valueOf` are great examples that could compromise a lot of real-world code. Being `Symbols` new we should probably/hopefully get them in the right way. I feel like throwing either cases is the right way. That example above is pretty compelling for throw always consistency. Rick ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Implicit coercion of Symbols
Rick Waldron wrote: That example above is pretty compelling for throw always consistency. With a new Reflect.* API for converting a symbol to its diagnostic/debugging string? If you agree, please file a bugs.ecmascript.org ticket. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Implicit coercion of Symbols
The code will be incorrect if you pass any regular object in there. Why should symbol be any different? For me, its throwing behavior is just another thing that could crash server-side node.js process for no good reason. 04.01.2015, 04:44, "Tab Atkins Jr." jackalm...@gmail.com: On Jan 3, 2015 3:38 PM, "Rick Waldron" waldron.r...@gmail.com wrote: E. W/r to A and C, most code will need some kind of guard, just to avoid the exception, ie. either try/catch or `if (typeof s !== "symbol") ...` This isn't a cost introduced by the throwing behavior, it's one that'll have to happen in code regardless of what we decide, or else the code will be incorrect. You can never construct modified keys from a Symbol by concatenation, even if it stringifies.So your code either needs to be sure it won't be passed a Symbol, or else it needs to branch its behavior.~TJ,___es-discuss mailing listes-discuss@mozilla.orghttps://mail.mozilla.org/listinfo/es-discuss___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: {Spam?} Re: Implicit coercion of Symbols
Alex Kocharin wrote: The code will be incorrect if you pass any regular object in there. Why should symbol be any different? For me, its throwing behavior is just another thing that could crash server-side node.js process for no good reason. No good reason? Wrong. Just because bugs pass without exception doesn't mean we must continue the tradition. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Implicit coercion of Symbols
Does it have to be a Reflect.* method? It could be `Symbol.prototype.getDescription()` or a getter. On 04 Jan 2015, at 02:25, Brendan Eich bren...@mozilla.org wrote: Rick Waldron wrote: That example above is pretty compelling for throw always consistency. With a new Reflect.* API for converting a symbol to its diagnostic/debugging string? If you agree, please file a bugs.ecmascript.org ticket. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- Dr. Axel Rauschmayer a...@rauschma.de rauschma.de ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Implicit coercion of Symbols
On Sat Jan 03 2015 at 8:25:40 PM Brendan Eich bren...@mozilla.org wrote: Rick Waldron wrote: That example above is pretty compelling for throw always consistency. With a new Reflect.* API for converting a symbol to its diagnostic/debugging string? If you agree, please file a bugs.ecmascript.org ticket. https://bugs.ecmascript.org/show_bug.cgi?id=3509 Rick /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Implicit coercion of Symbols
Given that there is currently no way to get a string representation of a value in a guaranteed side-effect-free fashion, I think something generalized for all primitive and object types would be ideal. On Jan 3, 2015, at 9:17 PM, Axel Rauschmayer a...@rauschma.de wrote: Does it have to be a Reflect.* method? It could be `Symbol.prototype.getDescription()` or a getter. On 04 Jan 2015, at 02:25, Brendan Eich bren...@mozilla.org mailto:bren...@mozilla.org wrote: Rick Waldron wrote: That example above is pretty compelling for throw always consistency. With a new Reflect.* API for converting a symbol to its diagnostic/debugging string? If you agree, please file a bugs.ecmascript.org http://bugs.ecmascript.org/ ticket. /be ___ es-discuss mailing list es-discuss@mozilla.org mailto:es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- Dr. Axel Rauschmayer a...@rauschma.de mailto:a...@rauschma.de rauschma.de ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Implicit coercion of Symbols
04.01.2015, 04:58, "Brendan Eich" bren...@mozilla.org:Alex Kocharin wrote: The code will be incorrect if you pass any regular object in there. Why should symbol be any different? For me, its throwing behavior is just another thing that could crash server-side node.js process for no good reason.No good reason? Wrong.Just because bugs pass without exception doesn't mean we must continue the "tradition". It isn't always a bug. People could cast something to a string for debugging purposes like this:```function log(anything) { process.stdout.write(new Date().toJSON() + ' - ' + anything + '\n')}``` Right now it'll never throw. Well, unless you override `.toString()` to throw, which I've never seen to be done intentionally. With throwing Symbols we'll have innocuous-looking code which will cause an exception. And since _javascript_ developers don't usually have a history of using throw..catch everywhere (some even avoid it for performance reasons), the consequences could be quite dire. Thus, every single code snippet that use type casting will have to either be wrapped with try..catch or checked for `symbol` explicitly. Maybe we'll write libraries called "castAnythingToStringSafely" because of that (like json-stringify-safe is created because JSON.stringify throws). And it'll surely make things worse for the beginners who don't know language well enough to remember to add those workarounds everywhere. So yes, I think that the existence of the errors you mentioned isn't a good reason to throw. There is no way for the interpreter to check developer intentions, and the casting can be used for good. Also, if you want to prevent mistakes like `object['blah' + symbol]`, linters could be changed to forbid/warn about concatenation inside property names. It's their job to warn about suspicious behavior, _javascript_ spec should stay as simple as possible imho. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Implicit coercion of Symbols
On Sat Jan 03 2015 at 9:41:57 PM Alex Kocharin a...@kocharin.ru wrote: Also, if you want to prevent mistakes like `object['blah' + symbol]`, linters could be changed to forbid/warn about concatenation inside property names. How would a linter know that `symbol` was actually a Symbol? Rick ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Implicit coercion of Symbols
On 1/3/15 9:41 PM, Alex Kocharin wrote: function log(anything) { process.stdout.write(new Date().toJSON() + ' - ' + anything + '\n') } ``` Right now it'll never throw. Well, unless you override `.toString()` to throw, which I've never seen to be done intentionally. Just to nitpick, try: console.log( + HTMLAnchorElement.prototype); in your favorite browser and watch it throw precisely for this reason. Or load data:text/html,iframe src=http://www.ecma-international.org/;/iframe and try: console.log( + frames[0]); With throwing Symbols we'll have innocuous-looking code which will cause an exception. The innocuous-looking code will totally cause exceptions in the wild today depending on what you pass to it. -Boris ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Implicit coercion of Symbols
04.01.2015, 05:44, "Rick Waldron" waldron.r...@gmail.com:On Sat Jan 03 2015 at 9:41:57 PM Alex Kocharin a...@kocharin.ru wrote: Also, if you want to prevent mistakes like `object['blah' + symbol]`, linters could be changed to forbid/warn about concatenation inside property names. How would a linter know that `symbol` was actually a Symbol? It wouldn't. But if it warns about string concatenation inside square braces (means, string + variable, but not number + variable), it should be good enough. This is the error the spec is trying to prevent, isn't it? Of course, linter can't detect this: var x = 'foo' + Symbol('bar') object[x] = 123 But it will detect these existing errors: var x = { foo: 'bar' } object['foo' + x] = 123 I don't know what would have better error detection rate, but linter approach has two distinct advantages: 1. it allows to get a warning before compilation instead of crashing in runtime 2. it could be explicitly turned off when there is a false positive Isn't good enough? Well, I'm sure some people will write JS-to-JS compilers that allow runtime type checking, maybe use TypeScript, which will prevent a lot of other similar bugs. My point is: concatenating Symbols with other strings have legitimate uses. And _javascript_ shouldn't require any explicit type casting in order to do this, it isn't a statically typed language. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Implicit coercion of Symbols
Alex Kocharin wrote: 04.01.2015, 05:44, Rick Waldron waldron.r...@gmail.com: On Sat Jan 03 2015 at 9:41:57 PM Alex Kocharin a...@kocharin.ru mailto:a...@kocharin.ru wrote: Also, if you want to prevent mistakes like `object['blah' + symbol]`, linters could be changed to forbid/warn about concatenation inside property names. How would a linter know that `symbol` was actually a Symbol? It wouldn't. But if it warns about string concatenation inside square braces (means, string + variable, but not number + variable), it should be good enough. This is the error the spec is trying to prevent, isn't it? No. See the JQuery examples that bz provided. My point is: concatenating Symbols with other strings have legitimate uses. Name one. And javascript shouldn't require any explicit type casting in order to do this, it isn't a statically typed language. Static types have nothing to do with getting an error on implicit conversion. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Implicit coercion of Symbols
04.01.2015, 07:36, "Brendan Eich" bren...@mozilla.org: My point is: concatenating Symbols with other strings have legitimate uses.Name one.I did name one in another message. Logging. If somebody wants to output a variable just to see what it is, something like `console.log('hey, I got this: ' + variable)` would be a natural choice. People don't expect string concatenation to throw. So they will happily write something like: ```function debug() {} // logging function in development, no-op in production env function something(x) { debug('something called with ' + x)}``` Which would fail whenever somebody passes a symbol there. I would assume `console.log(array.join(','))` would work as long as `array` is a array. Right? Wrong. As long as there is a Symbol() in there, it would throw. And unexpected behavior is never a good thing. Yes, it does sound hypothetical, but so does `object['' + Symbol()]` case which throwing is supposed to solve. I don't believe that casting is that common of an issue to outweight all the costs this behavior introduces. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Implicit coercion of Symbols
One reason it might make sense to throw, is people converting values to string names for use as object properties. Reason you'd want to throw would be to prevent accidentally making the key useless (different from its original Symbol value). Haven't paid attention to the rationale, but that doesn't seem like a bad one. On Jan 2, 2015, at 6:26 PM, Rick Waldron waldron.r...@gmail.com wrote: Kyle Simpson brought this up on Twitter today and I think it deserves one last look. Here's an example of the issue: var sym = Symbol(description); sym + ; // Throws Meanwhile... var sym = Symbol(description); String(sym); // Symbol(description) * (* appears to be the convention that implementors have converged on) This is the only time that a thing in JavaScript throws when it encounters an implicit coercion operation. This detail appears to be problematic in that it's an unnecessary divergence from the language's normal behaviour. Ref: https://people.mozilla.org/~jorendorff/es6-draft.html#sec-addition-operator-plus-runtime-semantics-evaluation 11.a Rick ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Implicit coercion of Symbols
On Fri Jan 02 2015 at 7:53:22 PM Brendan Eich bren...@mozilla.org wrote: Caitlin Potter wrote: One reason it might make sense to throw, is people converting values to string names for use as object properties. Reason you'd want to throw would be to prevent accidentally making the key useless (different from its original Symbol value). This is exactly the reason. Yep, I just wanted to make sure the subject got some last minute airtime to make sure this is _really_ the way to go. I'll play the opposition here: is the hazard as compelling now as it was when it was first discussed? Now that implementors have had some time to work with Symbol, do proponents of throw still feel strongly? Of course, having String(x) and '' + x diverge is funky, but not novel: Sure, but the argument was re: the implicit coercion of built-ins. Rick js o = {valueOf(){return 42}, toString(){return 'haha'}} ({valueOf:function valueOf(){return 42}, toString:function toString(){return 'haha'}}) js String(o) haha js ''+o 42 /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Implicit coercion of Symbols
One reason it might make sense to throw, is people converting values to string names for use as object properties. Reason you'd want to throw would be to prevent accidentally making the key useless (different from its original Symbol value). This is exactly the reason. Of course, having String(x) and '' + x diverge is funky, but not novel: js o = {valueOf(){return 42}, toString(){return 'haha'}} ({valueOf:function valueOf(){return 42}, toString:function toString(){return 'haha'}}) js String(o) haha js ''+o 42 Playing devil’s advocate: How realistic a danger is this? Do people ever compose a property key for an object out of several pieces? It does add a fair amount of complexity for something that doesn’t seem that common. -- Dr. Axel Rauschmayer a...@rauschma.de rauschma.de ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Implicit coercion of Symbols
Kyle Simpson brought this up on Twitter today and I think it deserves one last look. Here's an example of the issue: var sym = Symbol(description); sym + ; // Throws Meanwhile... var sym = Symbol(description); String(sym); // Symbol(description) * (* appears to be the convention that implementors have converged on) This is the only time that a thing in JavaScript throws when it encounters an implicit coercion operation. This detail appears to be problematic in that it's an unnecessary divergence from the language's normal behaviour. Ref: https://people.mozilla.org/~jorendorff/es6-draft.html#sec-addition-operator-plus-runtime-semantics-evaluation 11.a Rick ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Implicit coercion of Symbols
Caitlin Potter wrote: One reason it might make sense to throw, is people converting values to string names for use as object properties. Reason you'd want to throw would be to prevent accidentally making the key useless (different from its original Symbol value). This is exactly the reason. Of course, having String(x) and '' + x diverge is funky, but not novel: js o = {valueOf(){return 42}, toString(){return 'haha'}} ({valueOf:function valueOf(){return 42}, toString:function toString(){return 'haha'}}) js String(o) haha js ''+o 42 /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Implicit coercion of Symbols
On 1/2/15 9:33 PM, Axel Rauschmayer wrote: Do people ever compose a property key for an object out of several pieces? On the web? All the time. -Boris ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Implicit coercion of Symbols
On 1/2/15 9:40 PM, Axel Rauschmayer wrote: Can you give an example? get: function( num ) { return num != null ? // Return just the one element from the set ( num 0 ? this[ num + this.length ] : this[ num ] ) : // Return all the elements in a clean array slice.call( this ); }, That's from jQuery 2.1.3. And from the same place: function cache( key, value ) { // Use (key + ) to avoid collision with native prototype properties (see Issue #157) if ( keys.push( key + ) Expr.cacheLength ) { // Only keep the most recent entries delete cache[ keys.shift() ]; } return (cache[ key + ] = value); } That's after looking through about 1/10 of the library. I'll bet there are more. I'll also bet this sort of thing appears in every single major library out there. -Boris ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Implicit coercion of Symbols
Can you give an example? On 03 Jan 2015, at 03:34, Boris Zbarsky bzbar...@mit.edu wrote: On 1/2/15 9:33 PM, Axel Rauschmayer wrote: Do people ever compose a property key for an object out of several pieces? On the web? All the time. -Boris ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- Dr. Axel Rauschmayer a...@rauschma.de rauschma.de ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss