score:9
are these arbitrary conventions, as good as any other one?
no, these are not arbitrary. the linearization is done this way because it's the only way that will give you a sane method resolution order (mro).
why traits are explored first than classes and not vice versa ?
this is only true for a given class definition, in that the traits it extends come before the class it extends. this follows from the fact that the super classes/traits are explored right-to-left—which brings us to your second point.
why traits are traversed right to left, instead of left to right ?
here's a very simple motivating example for this.
type mytype = t1 with t2
// creating new instance using alias
new mytype with t3
// creating new instance directly
new t1 with t2 with t3
we would expect both instances in the example above to have the same linearization. when using type aliases, we "stack" additional traits on the right-hand-side, therefore we'd expect the traits on the right-hand-side to have highest precedence in the mro, and therefore come first in the linearization.
here's a quick example i came up with illustrating the linearization of traits and classes:
class base { override def tostring = "base" }
trait a { abstract override def tostring = "a " + super.tostring }
trait b { abstract override def tostring = "b " + super.tostring }
trait c { abstract override def tostring = "c " + super.tostring }
trait d { abstract override def tostring = "d " + super.tostring }
trait e { abstract override def tostring = "e " + super.tostring }
trait f { abstract override def tostring = "f " + super.tostring }
class x extends base with a with b { override def tostring = "x " + super.tostring }
class y extends x with c with d { override def tostring = "y " + super.tostring }
class z extends y with e with f { override def tostring = "z " + super.tostring }
new z
// res0: z = z f e y d c x b a base
you can see from the tostring
output that the linearization here is z f e y d c x b a base
, which is exactly what i'd expect with the given hierarchy. for example, since z
extends y
, which mixes-in the trait c
, we would expect y
's behaviors to come before c
, but after z
and its mix-ins e
and f
.
a simple reference on this chapter 12 of programming in scala, first edition: traits. (i don't think this has changed recently, so the first edition should still be accurate.)
Source: stackoverflow.com
Related Query
- Rationale in Scala linearization function
- Difference between method and function in Scala
- What is the Scala annotation to ensure a tail recursive function is optimized?
- Defining a function with multiple implicit arguments in Scala
- Differences between these three ways of defining a function in Scala
- Scala underscore - ERROR: missing parameter type for expanded function
- Empty partial function in Scala
- Linearization order in Scala
- Run a function periodically in Scala
- Anonymous recursive function in Scala
- Is there any analog for Scala 'zip' function in Groovy?
- Example of the Scala aggregate function
- How do I implement a generic mathematical function in Scala
- Why to use empty parentheses in Scala if we can just use no parentheses to define a function which does not need any arguments?
- Implicit keyword before a parameter in anonymous function in Scala
- Matching function literals with quasiquotes in Scala
- scala anonymous function missing parameter type error
- Why does Scala not have a return/unit function defined for each monad (in contrast to Haskell)?
- Scala unexpectedly not being able to ascertain type for expanded function
- Explanation of the aggregate scala function
- Scala underscore minimal function
- Applying an argument list to curried function using foldLeft in Scala
- Where do you split long Scala function signatures?
- Function composition of methods, functions, and partially applied functions in Scala
- Writing a generic cast function Scala
- Synthetic Function "##" in scala
- How to return a function in scala
- Scala List function for grouping consecutive identical elements
- Multiline function literal as arguments in Scala
- Scala Passing Function with Argument
More Query from same tag
- Cloud Storage Client with Scala and Dataproc: missing libraries
- Run sbt tests in a particular order
- Why cannot use implicit in this scenario?
- get all keys of play.api.libs.json.JsValue
- unable to use multiple future of Boolean type in Scala
- Scala program - difficult to understand
- Syntax for Calling a variable-length parameter Scala function from Java?
- Context bound with Infix operator
- How to store date in MongoDB in ISO format instead of Long [Play, Scala and ReactiveMongo]?
- Trouble with Scala implicit arguments
- Reading one file as Map(K,V) and pass V as keys while reading the second file as Map
- Overwriting the parquet file throws exception in spark
- What does it mean to 'hash cons'?
- scala table row column implicit
- Extending AutoDerivation in Circe does not work
- Null Values in Scala Super Constructor?
- How to convert scalastyle-result.xml into readable report
- Squeryl clauses (from, select, like, where) are not working in intellij
- Scala: Spark exception when project includes Akka
- Spark cast column to sql type stored in string
- Scala pattern match on the type of two bind variables
- Extract nested expression with parser combinators
- Call scala script function
- Using Cypher CREATE command with properties map, from Java
- Json4s add JValue to JArray
- Do I need to persist a continuously updated RDD?
- How do you exclude class fields from SORM table definition?
- How to perform Unit testing on Spark Structured Streaming?
- How to get Scala future output into a separate variables
- How to write a Scala wrapper for javax.swing.Timer