'Why don't Scala traits allow constructor parameters?
I'm new to Scala, coming from Java, and I was just reading about traits. One thing that gets mentioned often is that traits don't (can't? won't?) have constructor parameters. I was curious to know if there was a reason for this.
Coming from a long ago maths/computer-science background I was was wondering if this was an inevitable consequence because of some language design decision, or if it was a conscious decision to avoid some inheritance/mix-in problem or another?
Was hoping someone might know because it feels like there might be something interesting behind the fact.
Solution 1:[1]
The other answers describe the language; I suspect your question may really be "why is it designed in this way".
I believe it arises out of the awkwardnesses and verboseness that would arise when extending multiple traits, especially with overrides and with types, and various mix-in strategies.
The Cake Pattern often results in various traits providing missing bits to each other in a way that is totally invisible - by design - in the mixing class. And mixing can be bi-directional, using self-types. So the construction of a class from traits can be a very messy business for the compiler. Scala often trades simplicity of compiler design and implementation for simplicity of language use and code reduction, and this is certainly a good example.
So while there may be simple, hierarchical cases where having a constructor might be useful and sufficient, it would almost certainly have to be redundant of other mechanisms for more difficult, non-hierarchical scenarios.
Solution 2:[2]
Scala 3 will allow trait parameters. Here's a sample from the docs
trait Greeting(val name: String) {
def msg = s"How are you, $name"
}
class C extends Greeting("Bob") {
println(msg)
}
Solution 3:[3]
The answer is: that's what Scala is right now.
But that might not be the case in the future: trait parameters can replace early initializers. (see Martin Odersky's recent Scala Days presentation page 34) Scala: Where It Came From & Where It is Going
Solution 4:[4]
Traits don't have constructor parameters because traits cannot be constructed. Given any trait T
it's not possible to instantiate any object of type exactly T
. You can override trait defs with vals though, so
trait Foo {
def bar: String
}
class Baz(override val bar: String) extends Foo
You can't construct them directly because new MyTrait {}
is actually sugar for an anonymous class of new Object with MyTrait {}
Solution 5:[5]
Trait is analog for Java Interface. The main difference is that trait can have default implementation for their methods.
So Java interfaces can't have constructor so do Scala traits
Solution 6:[6]
Scala 3 allows traits with parameters, just like classes have parameters.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Community |
Solution 2 | |
Solution 3 | lcn |
Solution 4 | Daenyth |
Solution 5 | Lucky Libora |
Solution 6 | shvahabi |