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
Post a Comment