File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Scala and the fly likes Scala mixin behavior Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Languages » Scala
Bookmark "Scala mixin behavior" Watch "Scala mixin behavior" New topic
Author

Scala mixin behavior

Garrett Rowe
Ranch Hand

Joined: Jan 17, 2006
Posts: 1296
I must admit there are still some pretty basic things about Scala that I don't understand. One of the most basic is the mixin behavior. I guess I originally thought the mixin was only applicable for methods not defined in the class that was being mixed in, obviously that's wrong.

Does exactly what I expect and prints:
In T.f
1


also does what I expect and prints:
In C.f
3

So far so good. Then I try

This is slightly unexpected. I thought i would get:
In C.f
3

But it actually prints:
In ET.f
2

And then for the totally unexpected:


Which I didn't even know would compile, but when it did i expected:
In ET.f
In T.f
1

But it actually printed:
In ET.f
In C.f
3

What are the rules of mixin inheritance in this case?


Some problems are so complex that you have to be highly intelligent and well informed just to be undecided about them. - Laurence J. Peter
Marc Peabody
pie sneak
Sheriff

Joined: Feb 05, 2003
Posts: 4727

The second one is the example that surprised me, but I don't think I'd ever trying mixing in a type that's already a superclass.

Anyway, it surprises me because the mixin declaration is supposed to get priority when method names overlap. I'm wondering if the compiler ignores the "with T" because T is already a parent type.

In the third example, we see this - the ET trait gets priority because it's the furthest to the right in the instantiation.

In the fourth example, the ET trait can only be mixed in with a class that extends T now because ET declared that it extends T. Since C extends T, it's safe to do a mixin of C with ET.

The override abstract/super.f combo works and this kind of strategy is usually meant for stacking abilities. The super call isn't so much a "parent" call like it is in Java, but instead hands off control to the next class or mixin trait in line... the next to the left in declaration of the instantiation. In your example, C with ET, ET's super hands off to C because C is the next to the left in the declaration.

You could try to explore this with:
val x = new C with T with ET
but it's consistent with example 2, where T will pretty much get ignored and super.f will jump over to C.

But trying:
val x = new C with EET with ET
with a definition of:
gives the result:
In EET.f
In ET.f
In C.f
3

That really baked my noodle. According to the rule... ET.f should have run first. But maybe this is like your second example where the extended trait (in this case ET) gets ignored. But it didn't get ignored completely. Now, does ET.f show up because the EET's super call had ET as the next in priority line... or was this an actual case of super calling the parent (the traditional meaning) rather than passing along to the next in line?

Well, if C is now changed to extend EET, the output only gives the output for C.

Or, if instead I make EET extend T instead of ET
trait ET extends T ...
trait EET extends T ...
class C extends T ...
val x = new C with EET with ET...
... I get the output:
In ET.f
In EET.f
In C.f
3

So here's my theory:
The rightmost gets priority unless the rightmost already is a parent or ancestor of either the class or another mixed in trait.
If that rightmost trait calls super, the trait looks through its parent structure. If its closest parent has the same method, that parent's method is called unless that parent is already a parent of the (leftmost) class. If the trait who called super does not find a match in one of its parents that isn't also a parent of the (leftmost) class, then the "next in line" (next one to the left) gets priority to answer the super call.
Repeat as necessary.
[ July 13, 2008: Message edited by: Marc Peabody ]

A good workman is known by his tools.
Garrett Rowe
Ranch Hand

Joined: Jan 17, 2006
Posts: 1296
Thanks for the explanation Marc, I'll have to mull this all over with a glass of wine to let it sink in (or a nice mixed drink -- if you'll forgive the pun)
Marc Peabody
pie sneak
Sheriff

Joined: Feb 05, 2003
Posts: 4727

When you think you've got it figured out, predict the output of this very tricky one:

 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Scala mixin behavior