Skip to content

Can we temporarily remove "cannot extend mixins" limitation? #32

Closed
@yjbanov

Description

@yjbanov

(branched off #31 (comment))

Goal

Migrate all mixins (not only super-mixins) to the new mixin syntax.

Background

Classes that were meant to be super-mixins already had restrictions matching those of the new mixin keyword. This makes the migration from class to mixin for super-mixins simple. That's not the case for non-super-mixins. Those classes are extended, implemented, and mixed in in the wild. Therefore changing what previously was declared as a class to a mixin breaks classes that used extends instead of with.

Proposal: temporarily allow extending mixins

  • It does not require migration of any code that uses mixins, only code that defines mixins
  • extends and with have no semantic differences observable by the developer
  • It does not conflict with the new mixin semantics

Beyond that, this allows us to remove the ability to derive a mixin as a non-breaking change. To do that we will have to overload what extends means.

Imagine this declaration:

class Foo extends Bar

The compiler first checks whether Bar is a mixin or a class.

If Bar is a mixin, then the compiler desugars the above declaration into:

class Foo extends Object with Bar

More generally, class Foo extends M1 with M2, ..., Mk desugars into class Foo extends Object with M1, M2, ..., Mk.

If Bar is a class, then it's a normal derivation. The lint prefer_mixin then can be used to help authors find classes used as mixins and convert them to mixin syntax without breaking their users.

This approach will allow converting the vast majority of mixins present in the Dart ecosystem to the new mixin syntax without breaking existing user code. For example, Flutter can update abstract class WidgetsBindingObserver to mixin WidgetsBindingObserver as a non-breaking change.

Changing from class to mixin still comes with mixin restrictions, just like new mixin proposal wants, such as:

  • mixins cannot extend other classes
  • mixins cannot have constructors and factories
  • mixins cannot be instantiated directly

These properties will protect mixin authors from accidentally breaking their users.

Discussions elsewhere

This topic was discussed on these other threads:

Updates

  • Added a "Goal" section
  • Removed argument that A extends M is simpler syntactically due to existence of A with M
  • Created a section with links to other discussions

@leafpetersen @lrhn @eernstg @Hixie

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions