The main reason for adding trait parameters is more regularity. If classes can take parameters, the same should hold for traits. There is a question about who gets to pass arguments to a trait, since traits can be multiply extended by several other traits or classes. The proposal has a simple answer to that question: The first class extending a parameterized trait must pass corresponding arguments. I believe this makes the proposal simple enough to be a win.
Another reason for adding trait parameters is that they can replace most of the use cases of early initializers, which we would like to eliminate. Early initializers are a complex and somewhat “exotic” language feature which many did not even know about. By contrast, trait parameters are simple, intuitive and they increase the regularity of the language.
This proposal is open for discussion in the community and will be discussed in our next SIP meeting, where we’ll take all your feedback into account for the approval/dismissal of this feature.
How does this interact with implicit parameter blocks?
trait Something1
trait Something2
trait A(implicit st1 : Something1)
trait B(implicit st2 : Something2)
trait AB extends A with B
implicit val myST1 = new Something1{}
implicit val myST2 = new Something2{}
class ABC extends AB //Should this work?
Can’t the compiler complete the missing “inheritance pieces” ?
trait Something1
trait Something2
trait A(implicit st1 : Something1)
trait B(implicit st2 : Something2)
trait AB extends A with B
implicit val myST1 = new Something1{}
implicit val myST2 = new Something2{}
class ABC extends AB //Compiler will automagically change the last line to
class ABC extends A with B with AB //Compile rewrite
Alternatively, it may be possible to do via plugin, scalafix, or IDE generation, but IF it is possible, then why shouldn’t the compiler just do it by itself?
Is there something I don’t see where? What kind of language rules could this break?
I would say that a class is where you fix the linearisation order. As long as you stay with traits, you don’t (statically) know where a super call will go. When you mix them all together into a class, you’ve now locked that order down.
After cursory reading I can’t see the answer, if it possible or not for abstract class to NOT pass parameters to inherited trite but delegate it to subclass (so that cab abstract class some time behave like trite regarding traits parameters passing)
In particular, is this snippet is valid?
trait Greeting(val name: String) {
def msg = s"How are you, $name"
}
abstract class C extends Greeting /*skip args - delegate to sub class*/ {
println(msg)
}
class D extends C with Greeting("Bill")
Or it could be only written as
trait Greeting(val name: String) {
def msg = s"How are you, $name"
}
abstract class C {
// delegate `Greeting` trait parameters passing to sub class*/
this: Greeting =>
println(msg)
}
class D extends C with Greeting("Bill")