Implement trait parameters (SIP)
See original GitHub issueWe would like to allow parameters to traits. These replace early definitions, which are complicated and hard to get right. The syntax already allows this. Excerpting from current SyntaxSummary.txt (the one for Scala 2 is analogous):
TmplDef ::= ([`case'] `class' | `trait') ClassDef
ClassDef ::= id [ClsTypeParamClause] [ConstrMods] ClsParamClauses TemplateOpt
TemplateOpt ::= [`extends' Template | [nl] TemplateBody]
Template ::= ConstrApps [TemplateBody] | TemplateBody
ConstrApps ::= ConstrApp {`with' ConstrApp}
ConstrApp ::= AnnotType {ArgumentExprs}
Parent traits can now be introduced as a type or as a constructor which can take arguments. The order of initialization of traits is unaffected by parameter passing - as always, traits are initialized in linearization order. The following rules ensure that every parameterized trait is passed an argument list exactly when it is initialized:
- Only classes can pass arguments to parent traits. Traits themselves can pass arguments no neither classes nor traits.
- If a class
C
implements a parameterized traitT
, and its superclass does not, thenT
must appear as a parent trait ofC
with arguments. By contrast, if the superclass ofC
also implementsT
, thenC
may not pass arguments toT
.
For example, assume the declarations
trait T(x: A)
trait U extends T
U
may not pass arguments to T
. On the other hand, a class implementing U
must ensure that T
obtains arguments for its parameters. So the following would be illegal:
class C extends U
We have to add the trait T
as a direct parent of C
. This can be done in one of two ways:
class C extends T(e) with U
class C extends U with T(e)
Both class definitions have the same linearization. T
is in each case initialized before U
since T
is inherited by U
.
The arguments to a trait are in each case evaluated immediately before the trait initializer is run (except for call-by-name arguments, which are always evaluated on demand).
This means that in the example above the expression e
is evaluated before the initializer of either T
or U
is run. On the other hand, assuming the declarations
trait V(x2: B)
class D extends T(e1) with V(e2)
the evaluation order would be e1
, initializer of T
, e2
, initializer of V
.
Issue Analytics
- State:
- Created 8 years ago
- Comments:5 (3 by maintainers)
Top GitHub Comments
Bread crumbs for future documenters:
trait Foo[T : Ordering]
.trait
andabstract class
, beyond the usual rule that you can only have oneclass
parent.Classes are the spine where everything else is initialized. You need a class, not a trait, to pass arguments to a super-trait.