scala - What's the difference between `trait ValueHolder { type ValueType }` and `trait ValueHolder[T] {}` -


this question has answer here:

when read source code of liftweb, found trait declarations:

trait valueholder {   type valuetype   def get: valuetype }  trait pvalueholder[t] extends valueholder {   type valuetype = t } 

my question is, following 2 trait declarations:

trait valueholder {     type valuetype }  trait valueholder[t] { } 

i think equal each other, there difference between them? 1 can or offer 1 can't?

the first 1 called abstract type member , second 1 close analog java generics, there not complete same. 2 different ways achieve same goal. martin odersky explained his interview, 1 reason having both abstract type members , generic type parameters orthogonality:

there have been 2 notions of abstraction: parameterization , abstract members. in java have both, depends on abstracting over. in java have abstract methods, can't pass method parameter. don't have abstract fields, can pass value parameter. , don't have abstract type members, can specify type parameter. in java have 3 of these, there's distinction abstraction principle can use kinds of things. , argue distinction arbitrary.

what did in scala try more complete , orthogonal. decided have same construction principles 3 sorts of members. can have abstract fields value parameters. can pass methods (or "functions") parameters, or can abstract on them. can specify types parameters, or can abstract on them. , conceptually can model 1 in terms of other. @ least in principle, can express every sort of parameterization form of object-oriented abstraction. in sense scala more orthogonal , complete language.

he described difference between abstract type members , generic type parameters can show in practice:

but in practice, when use type parameterization many different things, leads explosion of parameters, , usually, what's more, in bounds of parameters. @ 1998 ecoop, kim bruce, phil wadler, , had paper showed increase number of things don't know, typical program grow quadratically. there reasons not parameters, have these abstract members, because don't give quadratic blow up.

i think great , easy example given bill veners (the creator of scalatest):

// type parameter version trait fixturesuite[f] {   // ... } 

and

// type member version trait fixturesuite {   type f   // ... } 

in either case, f type of fixture parameter pass tests, suite subclasses make concrete. here's example of concrete suite of tests needs stringbuilder passed each test, using type parameter approach:

// type parameter version class mysuite extends fixturesuite[stringbuilder] {   // ... } 

and here's example of concrete suite of tests needs stringbuilder passed each test using abstract type member approach:

// type member version class mysuite extends fixturesuite {   type f = stringbuilder   // ... } 

for example, if want pass 3 different fixture objects tests, you'll able so, you'll need specify 3 types, 1 each parameter. type parameter approach choosen, suite classes have ended looking this:

// type parameter version class mysuite extends fixturesuite3[stringbuilder, listbuffer, stack] myhandyfixture {   // ... } 

whereas type member approach this:

// type member version class mysuite extends fixturesuite3 myhandyfixture {   // ... } 

so shows 2 approaches goal in achieving great modular abstraction. more on topic can read in this legendary paper on scalable components


Comments

Popular posts from this blog

javascript - Count length of each class -

What design pattern is this code in Javascript? -

hadoop - Restrict secondarynamenode to be installed and run on any other node in the cluster -