domenic at domenicdenicola.com (2013-10-13T02:27:38.591Z)
On Thu, Sep 26, 2013 at 9:11 AM, Kevin Smith <zenparsing at gmail.com> wrote:
> After thinking this over, I still remain unconvinced that symbols are the
> right solution to the problem. Besides the fact that they introduce (ever
> more) complexity to the object model, they simply do not work as a
> duck-typing strategy for the real, *multi-realm* world of Javascript.
> Sure, we can make a special case of standard library symbols such that
> they maintain identity across realms. But a solution which only works for
> special cases isn't a very good solution, is it?
>
The consensus included Allen writing proposal for user-defined well-known
symbol registration—these symbols would also maintain identity across
realms.
https://github.com/rwaldron/tc39-notes/blob/master/es6/2013-09/sept-18.md#consensusresolution-1
> Here is another proposal which avoids these pitfalls:
>
> 1) Identify all meta-layer hooks using a string that is not an identifier.
> The actual string used doesn't matter in this proposal, but for
> illustration purposes I'll use an "@"-prefix.
>
> 2) Define all meta-layer hooks as functions. Testing for the hook will
> involve [[Get]] followed by [[IsCallable]].
>
> For example, defining an iterable:
>
> class C { "@iterator"(...args) { /* ... */ } }
>
> Overriding the string tag:
>
> class C { "@toStringTag"() { return "[object C]"; } }
>
> - Since the property name is a non-identifer, it is unlikely to collide
> with any object members.
>
But these can still easily collide with <identifier-name-string> property access (of the same string name), so I don't understand how this is better, can you clarify?
- Since the value of the hook must be a function, it is unlikely to collide
> with keys in an object-as-map (e.g. a JSON object).
>
What about something like this?
```js
// event.js
let events = Symbol();
export class Emitter {
constructor() {
this[events] = Object.create(null);
}
on(type, handler) {...},
off(type, handler) {...}
emit(type, ...args) {...}
}
// program.js
import { Emitter } from "event";
class Serialport extends Emitter {
constructor() {
super();
// there is no way to accidentally pave
// over the `events` symbol property
}
}
```
If I try that with your proposal:
```js
// event.js
export class Emitter {
constructor() {
this["@events"] = Object.create(null);
}
on(type, handler) {...},
off(type, handler) {...}
emit(type, ...args) {...}
}
// program.js
import { Emitter } from "Event";
class Serialport extends Emitter {
constructor() {
super();
this["@events"] = "MINE";
}
}
```
On Thu, Sep 26, 2013 at 9:11 AM, Kevin Smith <zenparsing at gmail.com> wrote: > After thinking this over, I still remain unconvinced that symbols are the > right solution to the problem. Besides the fact that they introduce (ever > more) complexity to the object model, they simply do not work as a > duck-typing strategy for the real, *multi-realm* world of Javascript. > Sure, we can make a special case of standard library symbols such that > they maintain identity across realms. But a solution which only works for > special cases isn't a very good solution, is it? > The consensus included Allen writing proposal for user-defined well-known symbol registration—these symbols would also maintain identity across realms. https://github.com/rwaldron/tc39-notes/blob/master/es6/2013-09/sept-18.md#consensusresolution-1 > Here is another proposal which avoids these pitfalls: > > 1) Identify all meta-layer hooks using a string that is not an identifier. > The actual string used doesn't matter in this proposal, but for > illustration purposes I'll use an "@"-prefix. > > 2) Define all meta-layer hooks as functions. Testing for the hook will > involve [[Get]] followed by [[IsCallable]]. > > For example, defining an iterable: > > class C { "@iterator"(...args) { /* ... */ } } > > Overriding the string tag: > > class C { "@toStringTag"() { return "[object C]"; } } > > - Since the property name is a non-identifer, it is unlikely to collide > with any object members. > But these can still easily collide with <identifier-name-string> property access (of the same string name), so I don't understand how this is better, can you clarify? - Since the value of the hook must be a function, it is unlikely to collide > with keys in an object-as-map (e.g. a JSON object). > What about something like this? // event.js let events = Symbol(); export class Emitter { constructor() { this[events] = Object.create(null); } on(type, handler) {...}, off(type, handler) {...} emit(type, ...args) {...} } // program.js import { Emitter } from "event"; class Serialport extends Emitter { constructor() { super(); // there is no way to accidentally pave // over the `events` symbol property } } If I try that with your proposal: // event.js export class Emitter { constructor() { this["@events"] = Object.create(null); } on(type, handler) {...}, off(type, handler) {...} emit(type, ...args) {...} } // program.js import { Emitter } from "Event"; class Serialport extends Emitter { constructor() { super(); this["@events"] = "MINE"; } } Rick -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20130926/9440213f/attachment.html>