Definition mixins

Raul-Sebastian Mihăilă raul.mihaila at
Tue Nov 28 09:21:45 UTC 2017

> ---------- Forwarded message ----------
> From: dante federici <c.dante.federici at>
> To: es-discuss at
> Cc:
> Bcc:
> Date: Mon, 27 Nov 2017 22:22:11 +0000
> Subject: Re: Re: Definition mixins
> I'm having a little trouble parsing your proposed syntax. Can you
> formalize it a bit better? Am I write in guessing that it's more like sugar
> around bind and composition?
> Like, what's going on here?
>   mixin obj, mixinFunc1 as method1: privateState, privateStateObj;
I posted a link to a more formal proposal in one of the previous messages:
I updated the syntax in the meantime as indeed this initial one looks
confusing. So, instead, it is:

mixin obj: mixinFunc1, mixinFunc2 as method2: privateState1, privateState2;

or you could write it like this:

mixin obj:
    mixinFunc2 as method2:
        privateState1, privateState2;

For the semantics, please see the example in the github spec and the
semantics section:

> I guess I'm wondering why this would be a part of the language and not
> just helper functions and a library? Maybe it'd be helpful to represent
> your chess example using your proposed syntax...?
The most difficult part of implementing it as a library is managing the mix
objects that are passed to the mixin function providers. For instance:

class Context1 {
  #privateState = {x: 100};

  mixin this:

  mixin on this: mixinFunc3;

  method() {
    /* ... */

If mixinFunc1, mixinFunc2 come from the same module/script then they share
the mix object, so that mixinFunc1 can call mixinFunc2. If mixinFunc3 comes
from a different module, then it mustn't have access to the other mixin
functions. (Of course, if mixinFunc1 and mixinFunc2 become public methods
of the object, for instance if the `mixin on` syntax was used, then
mixinFunc3 would have access to them since it has access to the context
object.) You could provide an API to mix in functions that come from
different places (of course in this case you would need to be more aware
about where they come from, which in some cases might be a nuisance), and
the API could create the mix object and pass it. But what if the state you
want to share with mixinFunc1 is different from the one you share with
mixinFunc2? You have to create the mix object yourself and that can get
ugly. The way the proposal solves this is by using the [[ScriptOrModule]]
slot that functions have.

> Some questions (that may be moot once I actually understand your syntax):
> * How does it actually prevent colliding names?

You pick only the functions you're interested in. If two mixin function
provider expressions resolve to the same identifier name then you can avoid
conflicts by using the `as` syntax to give a custom name to the functions.
You could benefit from early errors semantics to get an error if you forget
to do that.

> * How does it interact with closures?

The way any regular objects and functions interact with closures, because
indeed it's largely just syntactic sugar.

> * How does it prevent mixins from colliding over shared state?
You choose what state you share with any of the mixin functions:

function mixinProvider1(obj, mix, state) { return () => {}; }
function mixinProvider2(obj, mix, state1, state2) { return () => {}; }

class Class {
  #privateState1 = {};
  #privateState2 = {};

  mixin this: mixinProvider1: this.#privateState1;
  mixin this: mixinProvider2: this.#privateState1, this.#privateState2;

If you think about all the possible scenarios you will observe that
standard syntax is much simpler than an API. Note that I also imagined a
second version for the semantics that you can find in the github spec.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the es-discuss mailing list