Self type inheritance in scala
Asked Answered
H

1

9

Say I have the following traits:

trait A

trait B { this: A => }

trait C extends B // { this: A => }

Compiler error: illegal inheritance; self-type C does not conform to B's selftype B with A
As expected if I uncomment the self type annotation, the compiler is happy.

I think it's quite obvious why C also needs this self type. What I don't understand why it can not "inherit" it from A if the compiler could already figure out that it's needed?

I think it could reduce the verbosity when you use self types with complicated hierarchies, especially if you mix in a big bunch of traits, each of them having its own self type.

I guess probably there is a good reason for the current behavior, I just could not find/figure out what it is.

At first I thought it might be related to mixin linearization, but it seems to me it does not play here (even if I had more traits mixed in with more complicated self types).

Would it cause ambiguities in some cases? If so, why can't it work when there is no ambiguity?

Or is it related to some difficulties in proper implementation of it?

I could find some discussions about the topic (like self type is not inherited), but they mostly just state the problem and conclude that's how it is without too much explanation and/or a solution (if it exists).

Hellcat answered 6/8, 2010 at 7:16 Comment(0)
O
1
trait C extends B with A

is not the only solution. You could also have

trait AA extends A
trait C extends B with AA

That is, everything that inherits the interface of A is accepted. If you must rely on a concrete implementation, you would chose a mixin; if the implementation is up to the user or you have a good reason for not specifying the mixin in the trait (for example to loosen dependency issues), you would make it a self-type.

Oxyacid answered 6/8, 2010 at 11:20 Comment(3)
I think it's clear for me what's the difference between mixing in a trait or make it a self type. My question is: assuming that I want the previous traits with self type and mixing as it is and the compiler can figure out that I need (at least) A as the self type of C why can't it automatically "add" it?Hellcat
I think that would be undesirable in many occasions as it would then compile without giving you the chance to specialise the class. And what to do when A is not available in the current scope? I believe that would be confusing and that inheritance and mixing should be made explicit. Also, when you want to save typing, you could define a trait CA extends C with A and use that.Oxyacid
Debilski, you are misunderstanding the question. The OP wants "trait C extends B" to be equivalent to "trait C extends B {this: A => }", not to "trait C extends B with A".Dicast

© 2022 - 2024 — McMap. All rights reserved.