6

I have a trait I (intermediary), a class M (mixer) mixing in the trait and a trait S (specific).

class M extends Something with S {
    def baz() = foo()
}

trait I {
    def foo(): { ...; bar(); ... }
    def bar()
}

trait S extends I {
    def bar() = 42
}

I serves as an intermediate layer between M and S, providing a common interface.

I have an implemented method foo in I that calls a method bar (not implemented in I but defined there). What I would like to achieve is that all traits extending I must implement bar, so that this would throw a compile time error because bar is not implemented:

trait Z extends I

Is this possible in Scala?

P.S.: I am aware of the answer of Force Scala trait to implement a certain method but I do not want that kind of explicit coupling.

3
  • You can't force a trait to implement something like that. Commented Oct 22, 2013 at 14:01
  • 1
    I'm curious, why do you need that? You'll get your compile error as soon as you try to have a concrete implementation of I (forcing you to provide a def bar). But a trait is by essence abstract... Commented Oct 22, 2013 at 14:28
  • I need it because the traits and the concrete implementation live in separate software packages. The traits are in a library that has no concrete usages of these traits. I could test for the correct implementation of these traits in my test suite. I would like it better, however, if the errors would already pop up at compile time (e.g. in my IDE). Commented Oct 22, 2013 at 15:11

3 Answers 3

1

I thought about structural subtyping:

trait I[T<: { def:foo:Unit}]

....

would that work for you?

Sign up to request clarification or add additional context in comments.

2 Comments

Is this what you have in mind? class M extends Object with S { def baz() = foo() } trait I[T <: { def bar(): Unit }] { def foo() { bar() } def bar() } trait S extends I[S] { def bar() = 42 } Because if so, then something like trait Q extends I[Q] { } still does not throw a compile time error.
yeah I thought sth like that.
1

It seems a use case for self types :

trait Z {
   self : I =>
}

The compiler will check that any class in a hierarchy including Z is or extends I.

2 Comments

Could you please add an example? I don't see how I get compile time errors out of it if trait Z does not define bar().
I think with self types it is still not possible to force a trait to implement a certain method. The compiler will throw an error if a class uses trait Z and Z did not provide an implementation. But as I said in a previous comment, I would like to catch the error earlier.
0

I don't know of any way in Scala to force a trait to have concrete implementations for all methods. You could write a macro that generated a small test class and then the compiler would verify that the test class was concrete. It shouldn't be too hard to write a macro that takes this code:

@VerifyAllMethodsConcrete
trait Z extends I { ... }

and transforms it into this code:

trait Z extends I { ... }
class TestClassForVerifyingConcreteMethodsOfZ { }

Now if trait Z does not override bar() there will be an early error that says TestClassForVerifyingConcreteMethodsOfZ needs to be abstract. This error message isn't perfectly clear but hopefully this does the early verification on Z that you want.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.