Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mixin arguments? #11

Open
Dragoteryx opened this issue Feb 4, 2020 · 3 comments
Open

Mixin arguments? #11

Dragoteryx opened this issue Feb 4, 2020 · 3 comments

Comments

@Dragoteryx
Copy link

Dragoteryx commented Feb 4, 2020

Why?

The current way of creating mixins allows passing arguments.

let MyMixin = (superclass, arg1, arg2) => class extends superclass {
  constructor(...args) {
    super(...args)
    this.arg1 = arg1;
    this.arg2 = arg2;
  }
}

class Test {}

class TestMixedIn extends MyMixin(Test, "a", "b) {}

However, this proposal doesn't include that functionnality, which I think is a shame as that would require us to use the old syntax when we want to use mixins with arguments.

It could be written this way:

mixin MyMixin(arg1, arg2) {
  constructor(...args) {
    super(...args)
    this.arg1 = arg1;
    this.arg2 = arg2;
  }
}

class Test {}

class TestMixedIn extends Test with MyMixin("a", "b) {}

The parenthesis would be optional if the mixin doesn't have any arguments. If the parenthesis are omitted even though the mixin has arguments then they would just be defined as undefined unless default values are defined. (similar to when using the new keyword)

mixin MyMixin(arg1 = "a", arg2 = "b") {
  constructor(...args) {
    super(...args)
    this.arg1 = arg1;
    this.arg2 = arg2;
  }
}

class Test {}

class TestMixedIn extends Test with MyMixin {}

Composition

Extending a mixin that has arguments would look like this:

mixin MyMixin(arg1, arg2) {
  ...
}

mixin MyCoolerMixin extends MyMixin("a", "b") {
  ...
}

Which desugars to this:

let MyMixin = (superclass, arg1, arg2) => class extends superclass {
  ...
}

let MyCoolerMixin = superclass => class extends MyMixin(superclass, "a", "b") {
  ...
}

Or like this:

mixin MyMixin(arg1, arg2) {
  ...
}

mixin MyCoolerMixin(arg1, arg2) extends MyMixin(arg1, arg2) {
  ...
}

Which desugars to this:

let MyMixin = (superclass, arg1, arg2) => class extends superclass {
  ...
}

let MyCoolerMixin = (superclass, arg1, arg2) => class extends MyMixin(superclass, arg1, arg2) {
  ...
}
@justinfagnani
Copy link
Collaborator

Mixin parameters are definitely useful in some cases, but I didn't include them yet in order to keep the proposal simple. You're right though, there's a pretty simple extension to allow parameters.

@richie50
Copy link

richie50 commented Feb 7, 2021

@Dragoteryx Can you explain why the calling super in the context takes some arguments. Sorry i'm just trying to understand

`let MyMixin = (superclass, arg1, arg2) => class extends superclass {
constructor(...args) {

why? assuming class T { constructor(){}} , what args are we initializing
super(...args)
this.arg1 = arg1;
this.arg2 = arg2;
}
}`

@snarbies
Copy link

Taking a cue from decorators, wouldn't it make sense that the accepted value in the mixin position could either be a mixin itself (class Mixed extends Base with MixinValue { }) or a called function that returns a mixin (class Mixed extends Base with MixinFactory(arg1, arg2) { })?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants