08/13 DEP Meeting notes

629 views
Skip to first unread message

Bob Nystrom

unread,
Aug 13, 2015, 1:15:48 PM8/13/15
to core...@dartlang.org, General Dart Discussion

Günter Zöchbauer

unread,
Aug 13, 2015, 2:31:34 PM8/13/15
to Dart Core Development, mi...@dartlang.org
I missed these updates. Always a lot of interesting arguments for and against new features.

I find it quite weird that classes ignore the extends part when used as mixin. 
Maybe I'm just a bit unfamiliar with this idea.
When the class used as mixin accesses members of its superclass, are these members then expected to be present in the class (or superclass of) where the mixin is applied to instead?

It would be great to at least propagate `const` where it is explicitly stated. Like nested const list + maps or arguments to const constructors.

Keep up the great work :)

Bob Nystrom

unread,
Aug 13, 2015, 3:33:38 PM8/13/15
to Günter Zöchbauer, Dart Core Development, General Dart Discussion
On Thu, Aug 13, 2015 at 11:31 AM, Günter Zöchbauer <gzo...@gmail.com> wrote:
I find it quite weird that classes ignore the extends part when used as mixin. 
Maybe I'm just a bit unfamiliar with this idea.

It's not just you. It seems that every single person is surprised by this when they first discover it. That's why we're discussing it—it seems to have a real usability problem.
 
When the class used as mixin accesses members of its superclass, are these members then expected to be present in the class (or superclass of) where the mixin is applied to instead?

Yup. Ensuring that statically is one of the challenges. It seems like the current proposal doesn't quite hit the mark yet.

Cheers!

- bob

Gilad Bracha

unread,
Aug 13, 2015, 3:56:35 PM8/13/15
to Bob Nystrom, Günter Zöchbauer, Dart Core Development, General Dart Discussion
Hi Gunter,


On Thu, Aug 13, 2015 at 12:33 PM, 'Bob Nystrom' via Dart Core Development <core...@dartlang.org> wrote:

On Thu, Aug 13, 2015 at 11:31 AM, Günter Zöchbauer <gzo...@gmail.com> wrote:
I find it quite weird that classes ignore the extends part when used as mixin. 
Maybe I'm just a bit unfamiliar with this idea.

The key misunderstanding seems to be that people think they are mixing in a class. What you actually mix-in is a mixin. The mixin is what a class adds to its superclass - intuitively, the stuff between the curly braces in the class declaration.  

A mixin is really a very special kind of function, one that takes a superclass S and returns a subclass of S.  A class is always associated with a mixin. You could think of class Foo extends Bar { ...} as 

FooMixin(S) { return class extends S {...}} // illegal in Dart of course

along with  

var Foo = FooMixin(Bar);

The with notation is really a syntax for applying these mixin functions.

class C extends S with M1 with M2 

is really 

class C extends (M2.mixin(M1.mixin(S)))

where M1 and M2 are classes, and X.mixin denotes the mixin function implicitly induced by class X. Having such a special notation for mixins may or may not help but is certainly more verbose, which nobody likes.

Of course, sometimes you do want to mixin all the elements of a class (except Object) and today you have to do that by hand.  Mixin composition is a feature that would do that for you. It is precisely analogous to function composition. I hope we can add that in due course. We're trying to build up to that using a clean compositional semantics. That also makes the implementation easier and cleaner. 

Once you understand the semantics, you realize that mixing in the entire inheritance chain only makes sense via mixin composition, just as applying a series of functions must be made explicit via function composition. 

In the end, software engineering isn't always trivial. Sometimes one has to learn new things. 

--
Cheers, Gilad

Bob Nystrom

unread,
Aug 13, 2015, 6:21:10 PM8/13/15
to Gilad Bracha, Günter Zöchbauer, Dart Core Development, General Dart Discussion
On Thu, Aug 13, 2015 at 12:56 PM, Gilad Bracha <gbr...@google.com> wrote:
The key misunderstanding seems to be that people think they are mixing in a class. What you actually mix-in is a mixin. The mixin is what a class adds to its superclass - intuitively, the stuff between the curly braces in the class declaration.  

A mixin is really a very special kind of function, one that takes a superclass S and returns a subclass of S.  A class is always associated with a mixin. You could think of class Foo extends Bar { ...} as 

FooMixin(S) { return class extends S {...}} // illegal in Dart of course

along with  

var Foo = FooMixin(Bar);

The with notation is really a syntax for applying these mixin functions.

class C extends S with M1 with M2 

is really 

class C extends (M2.mixin(M1.mixin(S)))

where M1 and M2 are classes, and X.mixin denotes the mixin function implicitly induced by class X. Having such a special notation for mixins may or may not help but is certainly more verbose, which nobody likes.

That is one way to interpret the language's semantics, but it's not the only way that is consistent with its visible behavior. The intuition that users seem to have is that the name of a class in a with clause refers to the mixin composition of it and all of its superclasses (except Object), and not just the class's own mixin. Up until this new proposal, those two concepts were indistinguishable since any class used as a mixin had no non-Object superclasses. Now that we're relaxing that, we have to decide what a class's name should refer to.

The clear feedback we're getting is that having it refer to only the class's mixin is counter-intuitive. We could just as easily define:

class M1Base {}
class M1 extends M1Base {}

class M2Base {}
class M2 extends M2Base {}

class C extends S with M1, M2

C > M2 M2Base M1 M1Base S

as really:

class C extends (M2.mixin(M2Base.mixin(M1.mixin(M1Base.mixin(S)))))

Or, in other words, define <class>.supercompose as the mixin composition of the class's mixin and all of its superclasses' sans Object, and then define with as really:

class C extends (M2.supercompose(M1.supercompose(S)))

Once you understand the semantics, you realize that mixing in the entire inheritance chain only makes sense via mixin composition, just as applying a series of functions must be made explicit via function composition. 

Sure, but in practice, people tend wrap up composition inside a named function.

Regardless of whether mixin composition should have an explicit syntax on its own, we have to decide what a class name refers to inside a with clause. It can't refer to the class itself because, as you said, a class isn't a mixin. One option is to have it be the class's mixin, but I think we have good usability evidence that that isn't the right choice if we start allowing with clauses to contain classes that have non-Object superclasses.

In the end, software engineering isn't always trivial. Sometimes one has to learn new things. 

There may be valid reasons to prefer one interpretation over the other, or perhaps we need syntax to let the user express either. But, either way, it is not ignorance on the part of our users that they intuit the latter while you had in mind the former when up until now Dart behaved such that both are equally valid interpretations.

- bob

Patrick Logan

unread,
Aug 13, 2015, 9:17:49 PM8/13/15
to Bob Nystrom, General Dart Discussion, core...@dartlang.org, Günter Zöchbauer, Gilad Bracha

Supporting both variations seems like too much. Supporting the proposal as defined is more flexible than the alternative described in this thread.

Günter Zöchbauer

unread,
Aug 14, 2015, 2:24:16 AM8/14/15
to Dart Misc, rnys...@google.com, gzo...@gmail.com, core...@dartlang.org
Gilad, thanks for the explanation! I haven't used mixins in other languages before Dart and didn't use them much in Dart yet. The main reason I posted was to get involved which helps me to better understand the reasoning and the concepts.
I don't have enough knowledge about this topic yet to form an opinion about the proposal. 

-- 
Cheers, Günter

--
Cheers, Gilad

Gilad Bracha

unread,
Aug 14, 2015, 3:50:35 PM8/14/15
to Joe Conway, Dart Misc, gzo...@gmail.com, core...@dartlang.org


On Fri, Aug 14, 2015 at 7:15 AM Joe Conway <joe.c...@stablekernel.com> wrote:
I missed the part on relaxing restrictions on mixin classes that triggered this, so if I'm off base, then feel free to disregard. 

What value is there to mixing in a class that has a non-Object superclass?

One never mixies in a class. One mixes in a mixin, derived from a class. If you apply that mixin to a superclass with the suitable properties, it will work fine. 

In your example, if Person had a start method (I know that's far fetched) things would work.  Somewhat more realistically, if you had a different implementation of Vehicle, you could apply Car to it.  More realistically still, people have wanted to compose chains of UI widgets in Polymer separate from their original inheritance chain. 

In general, the idea is that the class contributes some implementation that may depend on the interface of its superclass, and may be useful in the context of different implementations of that interface.
 

Joe Conway

unread,
Aug 14, 2015, 4:58:46 PM8/14/15
to Dart Misc, gbr...@google.com, gzo...@gmail.com, core...@dartlang.org
I missed the part on relaxing restrictions on mixin classes that triggered this, so if I'm off base, then feel free to disregard. 

What value is there to mixing in a class that has a non-Object superclass? It seems very confusing to allow that; I'd imagine that - depending on a programmer's previous experience - one would see this as simply a syntax to achieve multiple inheritance, which it is clearly not. And suppose this situation:

class Vehicle {
 
Engine engine;
  start
() { engine.start(); }
}

class Car extends Vehicle {
 turnKey
() { start(); }
}

class Driver extends Person with Car {}

var driver = new Driver()..turnKey();

Maybe I'm a simpleton, but I'm not sure what is supposed to happen here. Clearly, this should be an error, but then what would be the point of mixing in Car? As soon as it extends Vehicle, it "is a " vehicle, and there is no untangling of them.

I like how Dart handles classes/interfaces/mixins, but I also think Swift 2.0's is on to something with protocol extensions. I'd definitely be interested to hear the Dart team's take on protocol extensions in Swift.

Joe Conway

unread,
Aug 14, 2015, 4:58:46 PM8/14/15
to Dart Misc, joe.c...@stablekernel.com, gzo...@gmail.com, core...@dartlang.org


One never mixies in a class. One mixes in a mixin, derived from a class. If you apply that mixin to a superclass with the suitable properties, it will work fine. 

I suppose that is where the confusion comes in. A mixin is the delta of a class to its superclass, but the declaration syntax doesn't differentiate. The keyword 'class' always declares an interface, can declare a mixin provided conditions are met, and often declares a concrete class at the same time. I actually rather like that aspect of Dart, and once learned, I think it is a powerful idea to implicitly create so many facets in a single declaration.

My understanding is that restrictions will be eased, therefore, the class keyword more often implicitly declares a mixin than it currently does. Is that accurate? If so, the example I provided is an illustration of something that could be confusing. I suppose as long as error messaging is appropriate, this becomes a non-issue, but I wonder if the value outweighs the cost? That's something your team would understand a lot better than I.
 
In your example, if Person had a start method (I know that's far fetched) things would work.  Somewhat more realistically, if you had a different implementation of Vehicle, you could apply Car to it.  More realistically still, people have wanted to compose chains of UI widgets in Polymer separate from their original inheritance chain.  

That makes sense. The last generation of popular programming languages treated the class hierarchy as a top-down tree (oh and that one popular language that treated it as a graph of chaos) - Dart allows that and also allows for other ways to compose types without creating chaos.

However, the same problem you're identifying in Polymer is a problem in Cocoa and Cocoa Touch as well. We've had a lot of success using Swift's protocol extensions (and previously, the less formal version: Objective-C categories) in attacking this problem. I'm not sure if extensions are on the roadmap for Dart, or if they even fit in with the spirit of Dart, but they they have value when they fit the rest language.
 
On a side note, I have to say, Dart is one of the most flexible and powerful languages I've worked with, and really opens up doors to be clever without being confusing; and the transition from Objective-C was really easy. We've since adopted Dart as our go-to platform for web server development.

 

lihui

unread,
Aug 14, 2015, 6:41:16 PM8/14/15
to Dart Misc
keyword "class" always define a class,interface,mixin together which is very consistent.
the mixin defined by class which have super class is just the same as trait in scala. it (super class) specify contract for the target to be applied.

tatumizer-v0.2

unread,
Aug 20, 2015, 12:04:05 PM8/20/15
to Dart Misc, core...@dartlang.org
The feature looks cute and ingenious. 

If my understanding is correct, then in the context of:
class M extends I {...}
class C with M {...}

the first definition (of class M) should really read like this:
class M that_can_be_applied_as_mixin_to_any_class_that_implements I {...}

If this interpretation is true, then the the entire  reason why the idea looks so ingenious is:
Verb "extends" in the definition of M gets re-interpreted as the whole phrase
can_be_applied_as_mixin_to_any_class_that_implements. Cute!!!

Now my question is: are we really so short of words that we have to load the word "extends" with second, fairly non-obvious, meaning?
What harm would it make if language just defined  a new keyword? This can be done in many ways, e.g. (first one that comes to mind)
mixin class M for I {...} // explicitly says the class was designed as mixin; clearly specifies condition of use.

True, it won't look as ingenious - because it's straightforward - but maybe that's the whole point?
I'm sure this idea was considered. Please explain why it was rejected.




 

Erik Ernst

unread,
Aug 20, 2015, 12:28:03 PM8/20/15
to Dart Misc, Dart Core Development
I think it is a very old design decision for Dart that a class declaration should be usable both as a class (that is the class body `{..}` in that class declaration plus all the superclasses) and as a mixin (just the `{..}`). The point is that it is an extra complication in the language semantics (and syntax, for that matter) if a new "mixin-only kind of class declaration" is introduced.

I don't think that it would be a bad idea to distinguish mixins from classes, but if you don't want to do that then we will have to do things like reinterpreting `extends` and/or `implements`.



--
For other discussions, see https://groups.google.com/a/dartlang.org/
 
For HOWTO questions, visit http://stackoverflow.com/tags/dart
 
To file a bug report or feature request, go to http://www.dartbug.com/new

To unsubscribe from this group and stop receiving emails from it, send an email to misc+uns...@dartlang.org.



--
Erik Ernst  -  Google Danmark ApS
Skt Petri Passage 5, 2 sal, 1165 København K, Denmark
CVR no. 28866984

Bob Nystrom

unread,
Aug 20, 2015, 2:01:23 PM8/20/15
to General Dart Discussion, Dart Core Development
On Sun, Aug 16, 2015 at 5:45 PM, tatumizer-v0.2 <tatu...@gmail.com> wrote:
The feature looks cute and ingenious. 

If my understanding is correct, then in the context of:
class M extends I {...}
class C with M {...}

the first definition (of class M) should really read like this:
class M that_can_be_applied_as_mixin_to_any_class_that_implements I {...}

Yeah, that's about right.

If you think of a mixin that takes a superclass as an argument and returns a new class that is the composition of the mixin and that superclass, then "extends" is sort of like the type annotation for that superclass argument. It lets you constrain which superclasses can be used as the base that the mixin is applied to.
 

If this interpretation is true, then the the entire  reason why the idea looks so ingenious is:
Verb "extends" in the definition of M gets re-interpreted as the whole phrase
can_be_applied_as_mixin_to_any_class_that_implements. Cute!!!

Now my question is: are we really so short of words that we have to load the word "extends" with second, fairly non-obvious, meaning?
What harm would it make if language just defined  a new keyword? This can be done in many ways, e.g. (first one that comes to mind)
mixin class M for I {...} // explicitly says the class was designed as mixin; clearly specifies condition of use.

We could do this. In some ways, it parallels the "abstract" modifier on classes—you're still defining a class but the modifier tweaks its semantics and the set of allowed operations inside the body.

I don't think it's necessarily a bad idea, but the language team isn't keen on it in general. Dart tries to be as simple as possible so we're always hesitant to add new syntax and mechanism.

Cheers!

- bob

tatumizer-v0.2

unread,
Aug 21, 2015, 4:47:15 PM8/21/15
to Dart Misc, core...@dartlang.org
Does anybody feel that mixin might be a more fundamental concept than inheritance? Or it's only me?
Mixin can be described as a special type of class that tells you: give me definitions of methods f1, f2,... fN - and I will provide you with methods g1, g2,... gN for free. (Obviously, it can't be instantiated by itself).

If this is more fundamental concept, it deserves more prominent syntactic expression.

Maybe this is the rare case where some new syntax is justified? Please give it another thought ;-)


Filipe Morgado

unread,
Aug 21, 2015, 8:30:50 PM8/21/15
to Dart Misc
+1

an advanced mixin paradigm would do everything inheritance does.
(provided we correctly handle super call which I'm not sure how)

Daniel Joyce

unread,
Aug 22, 2015, 12:15:10 AM8/22/15
to Dart Misc

Always python mro for super..


--
For other discussions, see https://groups.google.com/a/dartlang.org/

For HOWTO questions, visit http://stackoverflow.com/tags/dart

To file a bug report or feature request, go to http://www.dartbug.com/new

To unsubscribe from this group and stop receiving emails from it, send an email to misc+uns...@dartlang.org.
--
Daniel Joyce

The meek shall inherit the Earth, for the brave will be among the stars.

Erik Ernst

unread,
Aug 26, 2015, 6:37:43 AM8/26/15
to Dart Misc, Dart Core Development
On Fri, Aug 21, 2015 at 10:47 PM, tatumizer-v0.2 <tatu...@gmail.com> wrote:
Does anybody feel that mixin might be a more fundamental concept than inheritance? Or it's only me?

No no, I'd usually think of the semantics of any kind of inheritance in terms of what it does to the mixins (to the extent that this makes sense, but it often works out nicely, and when it doesn't it may well be a sign that something hasn't been designed consistently ;-).

  best regards,

tatumizer-v0.2

unread,
Aug 26, 2015, 10:12:52 AM8/26/15
to Dart Misc, core...@dartlang.org
>  I'd usually think of the semantics of any kind of inheritance in terms of what it does to the mixins
It only proves that inheritance *currently* is more fundamental *for you*.
Try to change your perspective :)

>... and when it doesn't it may well be a sign that something hasn't been designed consistently 
That's what I'm talking about - you might see less problems if you revert the relationship between the two.

Erik Ernst

unread,
Aug 26, 2015, 10:36:58 AM8/26/15
to Dart Misc, Dart Core Development
Not sure I follow you here. ;^)

You said "mixins are more fundamental than inheritance", then I said "yes, mixins are more fundamental than inheritance", then you said 'Try to change your perspective' .. ?

But I do think that seeing problems (genuine ones, that is) is a useful type of activity, and I suspect that we'll be better at spotting problems with composite mechanisms (such as inheritance) if we understand them in terms of a more basic building block (such as mixin application).

Alex Tatumizer

unread,
Aug 26, 2015, 11:50:51 AM8/26/15
to mi...@dartlang.org
> You said "mixins are more fundamental than inheritance", then I said "yes, mixins are more fundamental than inheritance",
Eric, my apologies, I misunderstood your comment which started with "No, no" - I thought you disagreed, so I read everything you said backwards. Sorry again.

Reply all
Reply to author
Forward
0 new messages