Symbol for modifying property lookup?

classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

Symbol for modifying property lookup?

#!/JoePea
Does one exist? I'm imagining an implementation for

```
class Node extends new MultiClass(ImperativeBase, Transformable) {
}
```

/#!/JoePea

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Symbol for modifying property lookup?

Claude Pache

Le 12 juil. 2016 à 02:45, /#!/JoePea <[hidden email]> a écrit :

Does one exist? I'm imagining an implementation for

```
class Node extends new MultiClass(ImperativeBase, Transformable) {
}
```


I think that  Proxy is the tool for that purpose. 

How a symbol would work here, since you need a property lookup in order to find that symbol?

—Claude

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Symbol for modifying property lookup?

#!/JoePea
Thanks guys, Proxy is the one, but not supported natively enough yet unfortunately.

Here is the ES5 solution I came up with, which creates "proxy" methods on the "multiPrototype" of the new MultiClass:

```js
class MultiClass {
    constructor(...constructors) {
        let constructorName = ''
        let multiPrototype = {}

        console.log(' -- Creating new MultiClass.')

        for (let i=0, l=constructors.length; i<l; i+=1) {
            const constructor = constructors[i]

            constructorName += constructor.name + (i == l-1 ? '' : '+')
            // f.e. SomeClass_OtherClass_FooBar

            let props = SimplePropertyRetriever.getOwnAndPrototypeEnumerablesAndNonenumerables(constructor.prototype)
            for (let prop of props) {
                multiPrototype[prop] = constructor.prototype[prop]
                console.log(' --- prop', prop)
            }
        }

        // temporary object to store the new MultiClass constructor, because
        // using an object allows us to programmatically assign a name to the
        // function, which we otherwise cannot do without eval().
        let tmp = {

            // This new constructor doesn't do much, just has all the given
            // constructor prototypes mixed in to it's own prototype. Be sure to
            // call the each constructor manually in the class that extends this
            // new MultiClass.
            [constructorName]() {}

        }

        tmp[constructorName].prototype = multiPrototype

        return tmp[constructorName]
    }
}
```

Where `SimplePropertyRetriever` is taken from the MDN article [Enumerability and ownership of properties](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties#Obtaining_properties_by_enumerabilityownership). 

Example usage:

```js
class One {
    foo() {console.log('foo')}
}

class Two {
    constructor() {/* ... */}
    bar() {console.log('bar')}
}

class Three extends Two {
    constructor(...args) {
        super(...args)
        // ...
    }
    baz() {console.log('baz')}
}

class FooBar extends new MultiClass(Three, One) {
    constructor(...args) {
        super() // needed, although does nothing.

        // call each constructor.
        One.call(this, ...args)
        Three.call(this, ...args)
    }
    oh() {console.log('oh')}
    yeah() {console.log('yeah')}
}

let f = new FooBar

f.foo()
f.bar()
f.baz()
f.oh()
f.yeah()
```

Any ideas on how else to do it?

/#!/JoePea

On Tue, Jul 12, 2016 at 1:52 AM, Claude Pache <[hidden email]> wrote:

Le 12 juil. 2016 à 02:45, /#!/JoePea <[hidden email]> a écrit :

Does one exist? I'm imagining an implementation for

```
class Node extends new MultiClass(ImperativeBase, Transformable) {
}
```


I think that  Proxy is the tool for that purpose. 

How a symbol would work here, since you need a property lookup in order to find that symbol?

—Claude


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Symbol for modifying property lookup?

#!/JoePea
Oops, I forgot that ES6 classes can't be called using the `SomeClass.call(...)` form. Is there a workaround for that so that my constructor can call all of them (besides downgrading to ES5 classes)?

```js
class Foo extends new MultiClass(One, Two) {
  constructor(...args) {
    One.call(this, ...args)
​ // Error, not allowed​

   
​Two​
.call(this, ...args)
​ //
​Error​
, not allowed
​​
  }
}
```

/#!/JoePea

On Wed, Jul 13, 2016 at 1:49 AM, /#!/JoePea <[hidden email]> wrote:
Thanks guys, Proxy is the one, but not supported natively enough yet unfortunately.

Here is the ES5 solution I came up with, which creates "proxy" methods on the "multiPrototype" of the new MultiClass:

```js
class MultiClass {
    constructor(...constructors) {
        let constructorName = ''
        let multiPrototype = {}

        console.log(' -- Creating new MultiClass.')

        for (let i=0, l=constructors.length; i<l; i+=1) {
            const constructor = constructors[i]

            constructorName += constructor.name + (i == l-1 ? '' : '+')
            // f.e. SomeClass_OtherClass_FooBar

            let props = SimplePropertyRetriever.getOwnAndPrototypeEnumerablesAndNonenumerables(constructor.prototype)
            for (let prop of props) {
                multiPrototype[prop] = constructor.prototype[prop]
                console.log(' --- prop', prop)
            }
        }

        // temporary object to store the new MultiClass constructor, because
        // using an object allows us to programmatically assign a name to the
        // function, which we otherwise cannot do without eval().
        let tmp = {

            // This new constructor doesn't do much, just has all the given
            // constructor prototypes mixed in to it's own prototype. Be sure to
            // call the each constructor manually in the class that extends this
            // new MultiClass.
            [constructorName]() {}

        }

        tmp[constructorName].prototype = multiPrototype

        return tmp[constructorName]
    }
}
```

Where `SimplePropertyRetriever` is taken from the MDN article [Enumerability and ownership of properties](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties#Obtaining_properties_by_enumerabilityownership). 

Example usage:

```js
class One {
    foo() {console.log('foo')}
}

class Two {
    constructor() {/* ... */}
    bar() {console.log('bar')}
}

class Three extends Two {
    constructor(...args) {
        super(...args)
        // ...
    }
    baz() {console.log('baz')}
}

class FooBar extends new MultiClass(Three, One) {
    constructor(...args) {
        super() // needed, although does nothing.

        // call each constructor.
        One.call(this, ...args)
        Three.call(this, ...args)
    }
    oh() {console.log('oh')}
    yeah() {console.log('yeah')}
}

let f = new FooBar

f.foo()
f.bar()
f.baz()
f.oh()
f.yeah()
```

Any ideas on how else to do it?

/#!/JoePea

On Tue, Jul 12, 2016 at 1:52 AM, Claude Pache <[hidden email]> wrote:

Le 12 juil. 2016 à 02:45, /#!/JoePea <[hidden email]> a écrit :

Does one exist? I'm imagining an implementation for

```
class Node extends new MultiClass(ImperativeBase, Transformable) {
}
```


I think that  Proxy is the tool for that purpose. 

How a symbol would work here, since you need a property lookup in order to find that symbol?

—Claude



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Symbol for modifying property lookup?

kdex
Callable class constructors [1] have been discussed at some point.
They've been withdrawn [2] in favor of decorators [3], though.

[1] https://github.com/tc39/ecma262/blob/master/workingdocs/callconstructor.md
[2] https://github.com/tc39/proposals/blob/master/inactive-proposals.md#inactive-proposals
[3] https://github.com/wycats/javascript-decorators/blob/master/README.md

On Wednesday, July 13, 2016 2:24:10 AM CEST /#!/JoePea wrote:

> Oops, I forgot that ES6 classes can't be called using the
> `SomeClass.call(...)` form. Is there a workaround for that so that my
> constructor can call all of them (besides downgrading to ES5 classes)?
>
> ```js
> class Foo extends new MultiClass(One, Two) {
>   constructor(...args) {
>     One.call(this, ...args)
> ​ // Error, not allowed​
>
>
> ​Two​
> .call(this, ...args)​ //
> ​Error​
> , not allowed
> ​​
>   }
> }
> ```
>
> */#!/*JoePea
>
> On Wed, Jul 13, 2016 at 1:49 AM, /#!/JoePea <[hidden email]> wrote:
>
> > Thanks guys, Proxy is the one, but not supported natively enough yet
> > unfortunately.
> >
> > Here is the ES5 solution I came up with, which creates "proxy" methods on
> > the "multiPrototype" of the new MultiClass:
> >
> > ```js
> > class MultiClass {
> >     constructor(...constructors) {
> >         let constructorName = ''
> >         let multiPrototype = {}
> >
> >         console.log(' -- Creating new MultiClass.')
> >
> >         for (let i=0, l=constructors.length; i<l; i+=1) {
> >             const constructor = constructors[i]
> >
> >             constructorName += constructor.name + (i == l-1 ? '' : '+')
> >             // f.e. SomeClass_OtherClass_FooBar
> >
> >             let props =
> > SimplePropertyRetriever.getOwnAndPrototypeEnumerablesAndNonenumerables(constructor.prototype)
> >             for (let prop of props) {
> >                 multiPrototype[prop] = constructor.prototype[prop]
> >                 console.log(' --- prop', prop)
> >             }
> >         }
> >
> >         // temporary object to store the new MultiClass constructor,
> > because
> >         // using an object allows us to programmatically assign a name to
> > the
> >         // function, which we otherwise cannot do without eval().
> >         let tmp = {
> >
> >             // This new constructor doesn't do much, just has all the given
> >             // constructor prototypes mixed in to it's own prototype. Be
> > sure to
> >             // call the each constructor manually in the class that
> > extends this
> >             // new MultiClass.
> >             [constructorName]() {}
> >
> >         }
> >
> >         tmp[constructorName].prototype = multiPrototype
> >
> >         return tmp[constructorName]
> >     }
> > }
> > ```
> >
> > Where `SimplePropertyRetriever` is taken from the MDN article
> > [Enumerability and ownership of properties](
> > https://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties#Obtaining_properties_by_enumerabilityownership
> > ).
> >
> > Example usage:
> >
> > ```js
> > class One {
> >     foo() {console.log('foo')}
> > }
> >
> > class Two {
> >     constructor() {/* ... */}
> >     bar() {console.log('bar')}
> > }
> >
> > class Three extends Two {
> >     constructor(...args) {
> >         super(...args)
> >         // ...
> >     }
> >     baz() {console.log('baz')}
> > }
> >
> > class FooBar extends new MultiClass(Three, One) {
> >     constructor(...args) {
> >         super() // needed, although does nothing.
> >
> >         // call each constructor.
> >         One.call(this, ...args)
> >         Three.call(this, ...args)
> >     }
> >     oh() {console.log('oh')}
> >     yeah() {console.log('yeah')}
> > }
> >
> > let f = new FooBar
> >
> > f.foo()
> > f.bar()
> > f.baz()
> > f.oh()
> > f.yeah()
> > ```
> >
> > Any ideas on how else to do it?
> >
> > */#!/*JoePea
> >
> > On Tue, Jul 12, 2016 at 1:52 AM, Claude Pache <[hidden email]>
> > wrote:
> >
> >>
> >> Le 12 juil. 2016 à 02:45, /#!/JoePea <[hidden email]> a écrit :
> >>
> >> Does one exist? I'm imagining an implementation for
> >>
> >> ```
> >> class Node extends new MultiClass(ImperativeBase, Transformable) {
> >> }
> >> ```
> >>
> >>
> >> I think that  Proxy is the tool for that purpose.
> >>
> >> How a symbol would work here, since you need a property lookup in order
> >> to find that symbol?
> >>
> >> —Claude
> >>
> >
> >
>
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Symbol for modifying property lookup?

#!/JoePea
Thanks kdex.

In one of my cases, `A` extends `B` extends `C` just so that `A` can have characteristics of both `B` and `C`, but it doesn't actually make sense for `B` to extend `C` because `B` is not a more specific form of `C` -- `B` and `C` are completely unrelated classes; I'm extending `B` from `C` just for `A` to have both sets of characteristics.

How might decorators be used instead?

I found some good reading:


I am currently reading to get ideas on what I might do, but would love suggestions if you have any.

/#!/JoePea

On Wed, Jul 13, 2016 at 3:00 AM, kdex <[hidden email]> wrote:
Callable class constructors [1] have been discussed at some point.
They've been withdrawn [2] in favor of decorators [3], though.

[1] https://github.com/tc39/ecma262/blob/master/workingdocs/callconstructor.md
[2] https://github.com/tc39/proposals/blob/master/inactive-proposals.md#inactive-proposals
[3] https://github.com/wycats/javascript-decorators/blob/master/README.md

On Wednesday, July 13, 2016 2:24:10 AM CEST /#!/JoePea wrote:
> Oops, I forgot that ES6 classes can't be called using the
> `SomeClass.call(...)` form. Is there a workaround for that so that my
> constructor can call all of them (besides downgrading to ES5 classes)?
>
> ```js
> class Foo extends new MultiClass(One, Two) {
>   constructor(...args) {
>     One.call(this, ...args)
> ​ // Error, not allowed​
>
>
> ​Two​
> .call(this, ...args)​ //
> ​Error​
> , not allowed
> ​​
>   }
> }
> ```
>
> */#!/*JoePea
>
> On Wed, Jul 13, 2016 at 1:49 AM, /#!/JoePea <[hidden email]> wrote:
>
> > Thanks guys, Proxy is the one, but not supported natively enough yet
> > unfortunately.
> >
> > Here is the ES5 solution I came up with, which creates "proxy" methods on
> > the "multiPrototype" of the new MultiClass:
> >
> > ```js
> > class MultiClass {
> >     constructor(...constructors) {
> >         let constructorName = ''
> >         let multiPrototype = {}
> >
> >         console.log(' -- Creating new MultiClass.')
> >
> >         for (let i=0, l=constructors.length; i<l; i+=1) {
> >             const constructor = constructors[i]
> >
> >             constructorName += constructor.name + (i == l-1 ? '' : '+')
> >             // f.e. SomeClass_OtherClass_FooBar
> >
> >             let props =
> > SimplePropertyRetriever.getOwnAndPrototypeEnumerablesAndNonenumerables(constructor.prototype)
> >             for (let prop of props) {
> >                 multiPrototype[prop] = constructor.prototype[prop]
> >                 console.log(' --- prop', prop)
> >             }
> >         }
> >
> >         // temporary object to store the new MultiClass constructor,
> > because
> >         // using an object allows us to programmatically assign a name to
> > the
> >         // function, which we otherwise cannot do without eval().
> >         let tmp = {
> >
> >             // This new constructor doesn't do much, just has all the given
> >             // constructor prototypes mixed in to it's own prototype. Be
> > sure to
> >             // call the each constructor manually in the class that
> > extends this
> >             // new MultiClass.
> >             [constructorName]() {}
> >
> >         }
> >
> >         tmp[constructorName].prototype = multiPrototype
> >
> >         return tmp[constructorName]
> >     }
> > }
> > ```
> >
> > Where `SimplePropertyRetriever` is taken from the MDN article
> > [Enumerability and ownership of properties](
> > https://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties#Obtaining_properties_by_enumerabilityownership
> > ).
> >
> > Example usage:
> >
> > ```js
> > class One {
> >     foo() {console.log('foo')}
> > }
> >
> > class Two {
> >     constructor() {/* ... */}
> >     bar() {console.log('bar')}
> > }
> >
> > class Three extends Two {
> >     constructor(...args) {
> >         super(...args)
> >         // ...
> >     }
> >     baz() {console.log('baz')}
> > }
> >
> > class FooBar extends new MultiClass(Three, One) {
> >     constructor(...args) {
> >         super() // needed, although does nothing.
> >
> >         // call each constructor.
> >         One.call(this, ...args)
> >         Three.call(this, ...args)
> >     }
> >     oh() {console.log('oh')}
> >     yeah() {console.log('yeah')}
> > }
> >
> > let f = new FooBar
> >
> > f.foo()
> > f.bar()
> > f.baz()
> > f.oh()
> > f.yeah()
> > ```
> >
> > Any ideas on how else to do it?
> >
> > */#!/*JoePea
> >
> > On Tue, Jul 12, 2016 at 1:52 AM, Claude Pache <[hidden email]>
> > wrote:
> >
> >>
> >> Le 12 juil. 2016 à 02:45, /#!/JoePea <[hidden email]> a écrit :
> >>
> >> Does one exist? I'm imagining an implementation for
> >>
> >> ```
> >> class Node extends new MultiClass(ImperativeBase, Transformable) {
> >> }
> >> ```
> >>
> >>
> >> I think that  Proxy is the tool for that purpose.
> >>
> >> How a symbol would work here, since you need a property lookup in order
> >> to find that symbol?
> >>
> >> —Claude
> >>
> >
> >
>


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Symbol for modifying property lookup?

Jordan Harband
https://facebook.github.io/react/blog/2016/07/13/mixins-considered-harmful.html may also be a helpful read.

(fwiw, any Symbol to modify property lookup would not likely ship before Proxy was available, so "use Proxy" is a pretty solid suggestion for this)

On Wed, Jul 13, 2016 at 1:04 PM, /#!/JoePea <[hidden email]> wrote:
Thanks kdex.

In one of my cases, `A` extends `B` extends `C` just so that `A` can have characteristics of both `B` and `C`, but it doesn't actually make sense for `B` to extend `C` because `B` is not a more specific form of `C` -- `B` and `C` are completely unrelated classes; I'm extending `B` from `C` just for `A` to have both sets of characteristics.

How might decorators be used instead?

I found some good reading:


I am currently reading to get ideas on what I might do, but would love suggestions if you have any.

/#!/JoePea

On Wed, Jul 13, 2016 at 3:00 AM, kdex <[hidden email]> wrote:
Callable class constructors [1] have been discussed at some point.
They've been withdrawn [2] in favor of decorators [3], though.

[1] https://github.com/tc39/ecma262/blob/master/workingdocs/callconstructor.md
[2] https://github.com/tc39/proposals/blob/master/inactive-proposals.md#inactive-proposals
[3] https://github.com/wycats/javascript-decorators/blob/master/README.md

On Wednesday, July 13, 2016 2:24:10 AM CEST /#!/JoePea wrote:
> Oops, I forgot that ES6 classes can't be called using the
> `SomeClass.call(...)` form. Is there a workaround for that so that my
> constructor can call all of them (besides downgrading to ES5 classes)?
>
> ```js
> class Foo extends new MultiClass(One, Two) {
>   constructor(...args) {
>     One.call(this, ...args)
> ​ // Error, not allowed​
>
>
> ​Two​
> .call(this, ...args)​ //
> ​Error​
> , not allowed
> ​​
>   }
> }
> ```
>
> */#!/*JoePea
>
> On Wed, Jul 13, 2016 at 1:49 AM, /#!/JoePea <[hidden email]> wrote:
>
> > Thanks guys, Proxy is the one, but not supported natively enough yet
> > unfortunately.
> >
> > Here is the ES5 solution I came up with, which creates "proxy" methods on
> > the "multiPrototype" of the new MultiClass:
> >
> > ```js
> > class MultiClass {
> >     constructor(...constructors) {
> >         let constructorName = ''
> >         let multiPrototype = {}
> >
> >         console.log(' -- Creating new MultiClass.')
> >
> >         for (let i=0, l=constructors.length; i<l; i+=1) {
> >             const constructor = constructors[i]
> >
> >             constructorName += constructor.name + (i == l-1 ? '' : '+')
> >             // f.e. SomeClass_OtherClass_FooBar
> >
> >             let props =
> > SimplePropertyRetriever.getOwnAndPrototypeEnumerablesAndNonenumerables(constructor.prototype)
> >             for (let prop of props) {
> >                 multiPrototype[prop] = constructor.prototype[prop]
> >                 console.log(' --- prop', prop)
> >             }
> >         }
> >
> >         // temporary object to store the new MultiClass constructor,
> > because
> >         // using an object allows us to programmatically assign a name to
> > the
> >         // function, which we otherwise cannot do without eval().
> >         let tmp = {
> >
> >             // This new constructor doesn't do much, just has all the given
> >             // constructor prototypes mixed in to it's own prototype. Be
> > sure to
> >             // call the each constructor manually in the class that
> > extends this
> >             // new MultiClass.
> >             [constructorName]() {}
> >
> >         }
> >
> >         tmp[constructorName].prototype = multiPrototype
> >
> >         return tmp[constructorName]
> >     }
> > }
> > ```
> >
> > Where `SimplePropertyRetriever` is taken from the MDN article
> > [Enumerability and ownership of properties](
> > https://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties#Obtaining_properties_by_enumerabilityownership
> > ).
> >
> > Example usage:
> >
> > ```js
> > class One {
> >     foo() {console.log('foo')}
> > }
> >
> > class Two {
> >     constructor() {/* ... */}
> >     bar() {console.log('bar')}
> > }
> >
> > class Three extends Two {
> >     constructor(...args) {
> >         super(...args)
> >         // ...
> >     }
> >     baz() {console.log('baz')}
> > }
> >
> > class FooBar extends new MultiClass(Three, One) {
> >     constructor(...args) {
> >         super() // needed, although does nothing.
> >
> >         // call each constructor.
> >         One.call(this, ...args)
> >         Three.call(this, ...args)
> >     }
> >     oh() {console.log('oh')}
> >     yeah() {console.log('yeah')}
> > }
> >
> > let f = new FooBar
> >
> > f.foo()
> > f.bar()
> > f.baz()
> > f.oh()
> > f.yeah()
> > ```
> >
> > Any ideas on how else to do it?
> >
> > */#!/*JoePea
> >
> > On Tue, Jul 12, 2016 at 1:52 AM, Claude Pache <[hidden email]>
> > wrote:
> >
> >>
> >> Le 12 juil. 2016 à 02:45, /#!/JoePea <[hidden email]> a écrit :
> >>
> >> Does one exist? I'm imagining an implementation for
> >>
> >> ```
> >> class Node extends new MultiClass(ImperativeBase, Transformable) {
> >> }
> >> ```
> >>
> >>
> >> I think that  Proxy is the tool for that purpose.
> >>
> >> How a symbol would work here, since you need a property lookup in order
> >> to find that symbol?
> >>
> >> —Claude
> >>
> >
> >
>


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Symbol for modifying property lookup?

Andrea Giammarchi-2
to be fair, that post is about problems with React architecture or the way they use mixins, not necessarily with mixins in general.

All points are highly subjective and not so difficult to avoid.

```js
// do not invoke within mixin methods
// stuff that doesn't belong to the mixin
// so no `renderHeader` case or issue
var myMixin = {
  doSomething(some, thing) {
    // avoid problems with refactoring or name clashing
    myMixin.doStuff.apply(this, arguments);
  },
  doStuff(some, stuff) {
    // do something useful with this mixin
    // never call something not available
  }
};

// compose and use mixins without problems
class MyClass extends(myMixin) {
  // no problems on name clashing
  // override and use explicit methods
  doSomething() {
    myMixin.doSomething.call(this, 'some', 123);
    // eventually: myOtherMixin.doSomething.call(this, 'other');
  }
}

// same logic to merge mixins, either an object or a class to extend later on

// the third point is still a very React-centric issue as it's presented in there
```

Of course, borrowing method with some sugar would be a huge help so that

```js
var myMixin = {
  doSomething(some, thing) {
    this::myMixin.doStuff(some, thing);
  },
  doStuff(some, stuff) {
  }
};

class MyClass extends(myMixin) {
  doSomething() {
    this::myMixin.doSomething('some', 123);
  }
}

```

But IIRC that proposal has been put on hold, it's on stage 0 or not sure whatever happened.

If it was usable maybe, the React post, would have been a different story (like ... "How to avoid mixins problems")

Best Regards





On Wed, Jul 13, 2016 at 9:41 PM, Jordan Harband <[hidden email]> wrote:
https://facebook.github.io/react/blog/2016/07/13/mixins-considered-harmful.html may also be a helpful read.

(fwiw, any Symbol to modify property lookup would not likely ship before Proxy was available, so "use Proxy" is a pretty solid suggestion for this)

On Wed, Jul 13, 2016 at 1:04 PM, /#!/JoePea <[hidden email]> wrote:
Thanks kdex.

In one of my cases, `A` extends `B` extends `C` just so that `A` can have characteristics of both `B` and `C`, but it doesn't actually make sense for `B` to extend `C` because `B` is not a more specific form of `C` -- `B` and `C` are completely unrelated classes; I'm extending `B` from `C` just for `A` to have both sets of characteristics.

How might decorators be used instead?

I found some good reading:


I am currently reading to get ideas on what I might do, but would love suggestions if you have any.

/#!/JoePea

On Wed, Jul 13, 2016 at 3:00 AM, kdex <[hidden email]> wrote:
Callable class constructors [1] have been discussed at some point.
They've been withdrawn [2] in favor of decorators [3], though.

[1] https://github.com/tc39/ecma262/blob/master/workingdocs/callconstructor.md
[2] https://github.com/tc39/proposals/blob/master/inactive-proposals.md#inactive-proposals
[3] https://github.com/wycats/javascript-decorators/blob/master/README.md

On Wednesday, July 13, 2016 2:24:10 AM CEST /#!/JoePea wrote:
> Oops, I forgot that ES6 classes can't be called using the
> `SomeClass.call(...)` form. Is there a workaround for that so that my
> constructor can call all of them (besides downgrading to ES5 classes)?
>
> ```js
> class Foo extends new MultiClass(One, Two) {
>   constructor(...args) {
>     One.call(this, ...args)
> ​ // Error, not allowed​
>
>
> ​Two​
> .call(this, ...args)​ //
> ​Error​
> , not allowed
> ​​
>   }
> }
> ```
>
> */#!/*JoePea
>
> On Wed, Jul 13, 2016 at 1:49 AM, /#!/JoePea <[hidden email]> wrote:
>
> > Thanks guys, Proxy is the one, but not supported natively enough yet
> > unfortunately.
> >
> > Here is the ES5 solution I came up with, which creates "proxy" methods on
> > the "multiPrototype" of the new MultiClass:
> >
> > ```js
> > class MultiClass {
> >     constructor(...constructors) {
> >         let constructorName = ''
> >         let multiPrototype = {}
> >
> >         console.log(' -- Creating new MultiClass.')
> >
> >         for (let i=0, l=constructors.length; i<l; i+=1) {
> >             const constructor = constructors[i]
> >
> >             constructorName += constructor.name + (i == l-1 ? '' : '+')
> >             // f.e. SomeClass_OtherClass_FooBar
> >
> >             let props =
> > SimplePropertyRetriever.getOwnAndPrototypeEnumerablesAndNonenumerables(constructor.prototype)
> >             for (let prop of props) {
> >                 multiPrototype[prop] = constructor.prototype[prop]
> >                 console.log(' --- prop', prop)
> >             }
> >         }
> >
> >         // temporary object to store the new MultiClass constructor,
> > because
> >         // using an object allows us to programmatically assign a name to
> > the
> >         // function, which we otherwise cannot do without eval().
> >         let tmp = {
> >
> >             // This new constructor doesn't do much, just has all the given
> >             // constructor prototypes mixed in to it's own prototype. Be
> > sure to
> >             // call the each constructor manually in the class that
> > extends this
> >             // new MultiClass.
> >             [constructorName]() {}
> >
> >         }
> >
> >         tmp[constructorName].prototype = multiPrototype
> >
> >         return tmp[constructorName]
> >     }
> > }
> > ```
> >
> > Where `SimplePropertyRetriever` is taken from the MDN article
> > [Enumerability and ownership of properties](
> > https://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties#Obtaining_properties_by_enumerabilityownership
> > ).
> >
> > Example usage:
> >
> > ```js
> > class One {
> >     foo() {console.log('foo')}
> > }
> >
> > class Two {
> >     constructor() {/* ... */}
> >     bar() {console.log('bar')}
> > }
> >
> > class Three extends Two {
> >     constructor(...args) {
> >         super(...args)
> >         // ...
> >     }
> >     baz() {console.log('baz')}
> > }
> >
> > class FooBar extends new MultiClass(Three, One) {
> >     constructor(...args) {
> >         super() // needed, although does nothing.
> >
> >         // call each constructor.
> >         One.call(this, ...args)
> >         Three.call(this, ...args)
> >     }
> >     oh() {console.log('oh')}
> >     yeah() {console.log('yeah')}
> > }
> >
> > let f = new FooBar
> >
> > f.foo()
> > f.bar()
> > f.baz()
> > f.oh()
> > f.yeah()
> > ```
> >
> > Any ideas on how else to do it?
> >
> > */#!/*JoePea
> >
> > On Tue, Jul 12, 2016 at 1:52 AM, Claude Pache <[hidden email]>
> > wrote:
> >
> >>
> >> Le 12 juil. 2016 à 02:45, /#!/JoePea <[hidden email]> a écrit :
> >>
> >> Does one exist? I'm imagining an implementation for
> >>
> >> ```
> >> class Node extends new MultiClass(ImperativeBase, Transformable) {
> >> }
> >> ```
> >>
> >>
> >> I think that  Proxy is the tool for that purpose.
> >>
> >> How a symbol would work here, since you need a property lookup in order
> >> to find that symbol?
> >>
> >> —Claude
> >>
> >
> >
>


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Symbol for modifying property lookup?

#!/JoePea
I read that React mixins article, and I think those are all good points, but in my case I am after multiple-inheritance, which seems to be a good use-case for mixins (as in that article by Justin Fagnani above), a somewhat different use case than the ones in the React article.

I'm attempting to take a mixin-based approach (with ideas inspired from [mixwith.js](https://github.com/justinfagnani/mixwith.js/issues/new)), who's outer API usage looks like this:

```js
import multiple from 'somewhere-yet-to-exist'

class Foo {}
class Bar extends Foo {}
(new Bar) instanceof Foo // true

let Klass = multiple(Foo) // take note!
class Baz extends Klass {}
(new Baz) instanceof Klass // true
(new Baz) instanceof Foo // true (is this possible?)

class Lorem {}
let Clazz = multiple(Foo, Lorem) // take note!
class Ipsum extends Clazz {}
(new Ipsum) instanceof Clazz // true
(new Ipsum) instanceof Foo // true (is this possible?)
(new Ipsum) instanceof Lorem // true (is this possible?)
```

Or, in other words, I hope it's possible to make this possible:

```js
import multiple from 'somewhere-yet-to-exist'

class Foo {}
class Lorem {}

// --- extend one class:
class Something extends Lorem {}

// --- extend more than one class:
class SomethingElse extends multiple(Foo, Lorem) {}

// --- instanceof should work:
(new Something) instanceof Lorem // true
(new SomethingElse) instanceof Lorem // true
```

I suppose I'll know if it's possible after I try implementing it. :D

/#!/JoePea

On Wed, Jul 13, 2016 at 2:25 PM, Andrea Giammarchi <[hidden email]> wrote:
to be fair, that post is about problems with React architecture or the way they use mixins, not necessarily with mixins in general.

All points are highly subjective and not so difficult to avoid.

```js
// do not invoke within mixin methods
// stuff that doesn't belong to the mixin
// so no `renderHeader` case or issue
var myMixin = {
  doSomething(some, thing) {
    // avoid problems with refactoring or name clashing
    myMixin.doStuff.apply(this, arguments);
  },
  doStuff(some, stuff) {
    // do something useful with this mixin
    // never call something not available
  }
};

// compose and use mixins without problems
class MyClass extends(myMixin) {
  // no problems on name clashing
  // override and use explicit methods
  doSomething() {
    myMixin.doSomething.call(this, 'some', 123);
    // eventually: myOtherMixin.doSomething.call(this, 'other');
  }
}

// same logic to merge mixins, either an object or a class to extend later on

// the third point is still a very React-centric issue as it's presented in there
```

Of course, borrowing method with some sugar would be a huge help so that

```js
var myMixin = {
  doSomething(some, thing) {
    this::myMixin.doStuff(some, thing);
  },
  doStuff(some, stuff) {
  }
};

class MyClass extends(myMixin) {
  doSomething() {
    this::myMixin.doSomething('some', 123);
  }
}

```

But IIRC that proposal has been put on hold, it's on stage 0 or not sure whatever happened.

If it was usable maybe, the React post, would have been a different story (like ... "How to avoid mixins problems")

Best Regards





On Wed, Jul 13, 2016 at 9:41 PM, Jordan Harband <[hidden email]> wrote:
https://facebook.github.io/react/blog/2016/07/13/mixins-considered-harmful.html may also be a helpful read.

(fwiw, any Symbol to modify property lookup would not likely ship before Proxy was available, so "use Proxy" is a pretty solid suggestion for this)

On Wed, Jul 13, 2016 at 1:04 PM, /#!/JoePea <[hidden email]> wrote:
Thanks kdex.

In one of my cases, `A` extends `B` extends `C` just so that `A` can have characteristics of both `B` and `C`, but it doesn't actually make sense for `B` to extend `C` because `B` is not a more specific form of `C` -- `B` and `C` are completely unrelated classes; I'm extending `B` from `C` just for `A` to have both sets of characteristics.

How might decorators be used instead?

I found some good reading:


I am currently reading to get ideas on what I might do, but would love suggestions if you have any.

/#!/JoePea

On Wed, Jul 13, 2016 at 3:00 AM, kdex <[hidden email]> wrote:
Callable class constructors [1] have been discussed at some point.
They've been withdrawn [2] in favor of decorators [3], though.

[1] https://github.com/tc39/ecma262/blob/master/workingdocs/callconstructor.md
[2] https://github.com/tc39/proposals/blob/master/inactive-proposals.md#inactive-proposals
[3] https://github.com/wycats/javascript-decorators/blob/master/README.md

On Wednesday, July 13, 2016 2:24:10 AM CEST /#!/JoePea wrote:
> Oops, I forgot that ES6 classes can't be called using the
> `SomeClass.call(...)` form. Is there a workaround for that so that my
> constructor can call all of them (besides downgrading to ES5 classes)?
>
> ```js
> class Foo extends new MultiClass(One, Two) {
>   constructor(...args) {
>     One.call(this, ...args)
> ​ // Error, not allowed​
>
>
> ​Two​
> .call(this, ...args)​ //
> ​Error​
> , not allowed
> ​​
>   }
> }
> ```
>
> */#!/*JoePea
>
> On Wed, Jul 13, 2016 at 1:49 AM, /#!/JoePea <[hidden email]> wrote:
>
> > Thanks guys, Proxy is the one, but not supported natively enough yet
> > unfortunately.
> >
> > Here is the ES5 solution I came up with, which creates "proxy" methods on
> > the "multiPrototype" of the new MultiClass:
> >
> > ```js
> > class MultiClass {
> >     constructor(...constructors) {
> >         let constructorName = ''
> >         let multiPrototype = {}
> >
> >         console.log(' -- Creating new MultiClass.')
> >
> >         for (let i=0, l=constructors.length; i<l; i+=1) {
> >             const constructor = constructors[i]
> >
> >             constructorName += constructor.name + (i == l-1 ? '' : '+')
> >             // f.e. SomeClass_OtherClass_FooBar
> >
> >             let props =
> > SimplePropertyRetriever.getOwnAndPrototypeEnumerablesAndNonenumerables(constructor.prototype)
> >             for (let prop of props) {
> >                 multiPrototype[prop] = constructor.prototype[prop]
> >                 console.log(' --- prop', prop)
> >             }
> >         }
> >
> >         // temporary object to store the new MultiClass constructor,
> > because
> >         // using an object allows us to programmatically assign a name to
> > the
> >         // function, which we otherwise cannot do without eval().
> >         let tmp = {
> >
> >             // This new constructor doesn't do much, just has all the given
> >             // constructor prototypes mixed in to it's own prototype. Be
> > sure to
> >             // call the each constructor manually in the class that
> > extends this
> >             // new MultiClass.
> >             [constructorName]() {}
> >
> >         }
> >
> >         tmp[constructorName].prototype = multiPrototype
> >
> >         return tmp[constructorName]
> >     }
> > }
> > ```
> >
> > Where `SimplePropertyRetriever` is taken from the MDN article
> > [Enumerability and ownership of properties](
> > https://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties#Obtaining_properties_by_enumerabilityownership
> > ).
> >
> > Example usage:
> >
> > ```js
> > class One {
> >     foo() {console.log('foo')}
> > }
> >
> > class Two {
> >     constructor() {/* ... */}
> >     bar() {console.log('bar')}
> > }
> >
> > class Three extends Two {
> >     constructor(...args) {
> >         super(...args)
> >         // ...
> >     }
> >     baz() {console.log('baz')}
> > }
> >
> > class FooBar extends new MultiClass(Three, One) {
> >     constructor(...args) {
> >         super() // needed, although does nothing.
> >
> >         // call each constructor.
> >         One.call(this, ...args)
> >         Three.call(this, ...args)
> >     }
> >     oh() {console.log('oh')}
> >     yeah() {console.log('yeah')}
> > }
> >
> > let f = new FooBar
> >
> > f.foo()
> > f.bar()
> > f.baz()
> > f.oh()
> > f.yeah()
> > ```
> >
> > Any ideas on how else to do it?
> >
> > */#!/*JoePea
> >
> > On Tue, Jul 12, 2016 at 1:52 AM, Claude Pache <[hidden email]>
> > wrote:
> >
> >>
> >> Le 12 juil. 2016 à 02:45, /#!/JoePea <[hidden email]> a écrit :
> >>
> >> Does one exist? I'm imagining an implementation for
> >>
> >> ```
> >> class Node extends new MultiClass(ImperativeBase, Transformable) {
> >> }
> >> ```
> >>
> >>
> >> I think that  Proxy is the tool for that purpose.
> >>
> >> How a symbol would work here, since you need a property lookup in order
> >> to find that symbol?
> >>
> >> —Claude
> >>
> >
> >
>


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss




_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

RE: Symbol for modifying property lookup?

doodad-js Admin

I did an implementation of mix-ins, traits and interfaces. It’s far to be perfect and it doesn’t integrate with the “class” construct, but if you are interested, my project is named “doodad-js” and you can download it from npm.

 

 

From: /#!/JoePea [mailto:[hidden email]]
Sent: Monday, July 18, 2016 12:55 AM
To: Andrea Giammarchi <[hidden email]>
Cc: es-discuss <[hidden email]>
Subject: Re: Symbol for modifying property lookup?

 

I read that React mixins article, and I think those are all good points, but in my case I am after multiple-inheritance, which seems to be a good use-case for mixins (as in that article by Justin Fagnani above), a somewhat different use case than the ones in the React article.

 

I'm attempting to take a mixin-based approach (with ideas inspired from [mixwith.js](https://github.com/justinfagnani/mixwith.js/issues/new)), who's outer API usage looks like this:

```js

import multiple from 'somewhere-yet-to-exist'

 

class Foo {}

class Bar extends Foo {}

(new Bar) instanceof Foo // true

 

let Klass = multiple(Foo) // take note!

class Baz extends Klass {}

(new Baz) instanceof Klass // true

(new Baz) instanceof Foo // true (is this possible?)

 

class Lorem {}

let Clazz = multiple(Foo, Lorem) // take note!

class Ipsum extends Clazz {}

(new Ipsum) instanceof Clazz // true

(new Ipsum) instanceof Foo // true (is this possible?)

(new Ipsum) instanceof Lorem // true (is this possible?)

```

 

Or, in other words, I hope it's possible to make this possible:

 

```js

import multiple from 'somewhere-yet-to-exist'

 

class Foo {}

class Lorem {}

 

// --- extend one class:

class Something extends Lorem {}

 

// --- extend more than one class:

class SomethingElse extends multiple(Foo, Lorem) {}

 

// --- instanceof should work:

(new Something) instanceof Lorem // true
(new SomethingElse) instanceof Lorem // true

```

 

I suppose I'll know if it's possible after I try implementing it. :D


/#!/JoePea

 

On Wed, Jul 13, 2016 at 2:25 PM, Andrea Giammarchi <[hidden email]> wrote:

to be fair, that post is about problems with React architecture or the way they use mixins, not necessarily with mixins in general.

 

All points are highly subjective and not so difficult to avoid.

 

```js

// do not invoke within mixin methods

// stuff that doesn't belong to the mixin

// so no `renderHeader` case or issue

var myMixin = {

  doSomething(some, thing) {

    // avoid problems with refactoring or name clashing

    myMixin.doStuff.apply(this, arguments);

  },

  doStuff(some, stuff) {

    // do something useful with this mixin

    // never call something not available

  }

};

 

// compose and use mixins without problems

class MyClass extends(myMixin) {

  // no problems on name clashing

  // override and use explicit methods

  doSomething() {

    myMixin.doSomething.call(this, 'some', 123);

    // eventually: myOtherMixin.doSomething.call(this, 'other');

  }

}

 

// same logic to merge mixins, either an object or a class to extend later on

 

// the third point is still a very React-centric issue as it's presented in there

```

 

Of course, borrowing method with some sugar would be a huge help so that

 

```js

var myMixin = {

  doSomething(some, thing) {

    this::myMixin.doStuff(some, thing);

  },

  doStuff(some, stuff) {

  }

};

 

class MyClass extends(myMixin) {

  doSomething() {

    this::myMixin.doSomething('some', 123);

  }

}

 

```

 

But IIRC that proposal has been put on hold, it's on stage 0 or not sure whatever happened.

 

If it was usable maybe, the React post, would have been a different story (like ... "How to avoid mixins problems")

 

Best Regards

 

 

 

 

 

On Wed, Jul 13, 2016 at 9:41 PM, Jordan Harband <[hidden email]> wrote:

https://facebook.github.io/react/blog/2016/07/13/mixins-considered-harmful.html may also be a helpful read.

 

(fwiw, any Symbol to modify property lookup would not likely ship before Proxy was available, so "use Proxy" is a pretty solid suggestion for this)

 

On Wed, Jul 13, 2016 at 1:04 PM, /#!/JoePea <[hidden email]> wrote:

Thanks kdex.

 

In one of my cases, `A` extends `B` extends `C` just so that `A` can have characteristics of both `B` and `C`, but it doesn't actually make sense for `B` to extend `C` because `B` is not a more specific form of `C` -- `B` and `C` are completely unrelated classes; I'm extending `B` from `C` just for `A` to have both sets of characteristics.

 

How might decorators be used instead?

 

I found some good reading:

 

 

I am currently reading to get ideas on what I might do, but would love suggestions if you have any.


/#!/JoePea

 

On Wed, Jul 13, 2016 at 3:00 AM, kdex <[hidden email]> wrote:

Callable class constructors [1] have been discussed at some point.
They've been withdrawn [2] in favor of decorators [3], though.

[1] https://github.com/tc39/ecma262/blob/master/workingdocs/callconstructor.md
[2] https://github.com/tc39/proposals/blob/master/inactive-proposals.md#inactive-proposals
[3] https://github.com/wycats/javascript-decorators/blob/master/README.md

On Wednesday, July 13, 2016 2:24:10 AM CEST /#!/JoePea wrote:


> Oops, I forgot that ES6 classes can't be called using the
> `SomeClass.call(...)` form. Is there a workaround for that so that my
> constructor can call all of them (besides downgrading to ES5 classes)?
>
> ```js
> class Foo extends new MultiClass(One, Two) {
>   constructor(...args) {
>     One.call(this, ...args)
> ​ // Error, not allowed​
>
>
> ​Two​
> .call(this, ...args)​ //
> ​Error​
> , not allowed
> ​​
>   }
> }
> ```
>
> */#!/*JoePea

>
> On Wed, Jul 13, 2016 at 1:49 AM, /#!/JoePea <[hidden email]> wrote:
>
> > Thanks guys, Proxy is the one, but not supported natively enough yet
> > unfortunately.
> >
> > Here is the ES5 solution I came up with, which creates "proxy" methods on
> > the "multiPrototype" of the new MultiClass:
> >
> > ```js
> > class MultiClass {
> >     constructor(...constructors) {
> >         let constructorName = ''
> >         let multiPrototype = {}
> >
> >         console.log(' -- Creating new MultiClass.')
> >
> >         for (let i=0, l=constructors.length; i<l; i+=1) {
> >             const constructor = constructors[i]
> >
> >             constructorName += constructor.name + (i == l-1 ? '' : '+')
> >             // f.e. SomeClass_OtherClass_FooBar
> >
> >             let props =
> > SimplePropertyRetriever.getOwnAndPrototypeEnumerablesAndNonenumerables(constructor.prototype)
> >             for (let prop of props) {
> >                 multiPrototype[prop] = constructor.prototype[prop]
> >                 console.log(' --- prop', prop)
> >             }
> >         }
> >
> >         // temporary object to store the new MultiClass constructor,
> > because
> >         // using an object allows us to programmatically assign a name to
> > the
> >         // function, which we otherwise cannot do without eval().
> >         let tmp = {
> >
> >             // This new constructor doesn't do much, just has all the given
> >             // constructor prototypes mixed in to it's own prototype. Be
> > sure to
> >             // call the each constructor manually in the class that
> > extends this
> >             // new MultiClass.
> >             [constructorName]() {}
> >
> >         }
> >
> >         tmp[constructorName].prototype = multiPrototype
> >
> >         return tmp[constructorName]
> >     }
> > }
> > ```
> >
> > Where `SimplePropertyRetriever` is taken from the MDN article
> > [Enumerability and ownership of properties](
> > https://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties#Obtaining_properties_by_enumerabilityownership
> > ).
> >
> > Example usage:
> >
> > ```js
> > class One {
> >     foo() {console.log('foo')}
> > }
> >
> > class Two {
> >     constructor() {/* ... */}
> >     bar() {console.log('bar')}
> > }
> >
> > class Three extends Two {
> >     constructor(...args) {
> >         super(...args)
> >         // ...
> >     }
> >     baz() {console.log('baz')}
> > }
> >
> > class FooBar extends new MultiClass(Three, One) {
> >     constructor(...args) {
> >         super() // needed, although does nothing.
> >
> >         // call each constructor.
> >         One.call(this, ...args)
> >         Three.call(this, ...args)
> >     }
> >     oh() {console.log('oh')}
> >     yeah() {console.log('yeah')}
> > }
> >
> > let f = new FooBar
> >
> > f.foo()
> > f.bar()
> > f.baz()
> > f.oh()
> > f.yeah()
> > ```
> >
> > Any ideas on how else to do it?
> >

> > */#!/*JoePea

> >
> > On Tue, Jul 12, 2016 at 1:52 AM, Claude Pache <[hidden email]>
> > wrote:
> >
> >>
> >> Le 12 juil. 2016 à 02:45, /#!/JoePea <[hidden email]> a écrit :
> >>
> >> Does one exist? I'm imagining an implementation for
> >>
> >> ```
> >> class Node extends new MultiClass(ImperativeBase, Transformable) {
> >> }
> >> ```
> >>
> >>
> >> I think that  Proxy is the tool for that purpose.
> >>
> >> How a symbol would work here, since you need a property lookup in order
> >> to find that symbol?
> >>
> >> —Claude
> >>
> >
> >
>

 

 

_______________________________________________

es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss

 


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss

 

 


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss