Scala: Abstract types vs generics -
i reading a tour of scala: abstract types. when better use abstract types?
for example,
abstract class buffer { type t val element: t }
rather generics, example,
abstract class buffer[t] { val element: t }
you have point of view on issue here:
the purpose of scala's type system
conversation martin odersky, part iii
bill venners , frank sommers (may 18, 2009)
update (october2009): follows below has been illustrated in new article bill venners:
abstract type members versus generic type parameters in scala (see summary @ end)
(here relevant extract of first interview, may 2009, emphasis mine)
general principle
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.
the scala way
we 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.
why?
what, in particular, abstract types buy nice treatment these covariance problems talked before.
1 standard problem, has been around long time, problem of animals , foods.
puzzle have class animal
method, eat
, eats food.
problem if subclass animal , have class such cow, eat grass , not arbitrary food. cow couldn't eat fish, instance.
want able cow has eat method eats grass , not other things.
actually, can't in java because turns out can construct unsound situations, problem of assigning fruit apple variable talked earlier.
the answer you add abstract type animal class.
say, new animal class has type of suitablefood
, don't know.
it's abstract type. don't give implementation of type. have eat
method eats suitablefood
.
, in cow
class say, ok, have cow, extends class animal
, , cow type suitablefood equals grass
.
abstract types provide notion of type in superclass don't know, fill in later in subclasses know.
same parameterization?
indeed can. parameterize class animal kind of food eats.
in practice, when many different things, leads explosion of parameters, , usually, what's more, in bounds of parameters.
@ 1998 ecoop, kim bruce, phil wadler, , had paper showed as 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.
thatismatt asks in comments:
do think following fair summary:
- abstract types used in 'has-a' or 'uses-a' relationships (e.g.
cow eats grass
)- where generics 'of' relationships (e.g.
list of ints
)
i not sure relationship different between using abstract types or generics. different is:
- how used, ,
- how parameter bounds managed.
to understand martin speaking when comes "explosion of parameters, , usually, what's more, in bounds of parameters", , subsequent quadratically growth when abstract type modeled using generics, can consider paper "scalable component abstraction" written by... martin odersky, , matthias zenger oopsla 2005, referenced in publications of project palcom (finished in 2007).
relevant extracts
definition
abstract type members provide flexible way abstract on concrete types of components.
abstract types can hide information internals of component, similar use in sml signatures. in object-oriented framework classes can extended inheritance, may used flexible means of parameterization (often called family polymorphism, see weblog entry instance, , paper written eric ernst).
(note: family polymorphism has been proposed object-oriented languages solution supporting reusable yet type-safe mutually recursive classes.
key idea of family polymorphism notion of families, used group mutually recursive classes)
bounded type abstraction
abstract class maxcell extends abscell { type t <: ordered { type o = t } def setmax(x: t) = if (get < x) set(x) }
here, type declaration of t constrained upper type bound consists of class name ordered , refinement
{ type o = t }
.
upper bound restricts specializations of t in subclasses subtypes of ordered type membero
ofequals t
.
because of constraint,<
method of class ordered guaranteed applicable receiver , argument of type t.
example shows bounded type member may appear part of bound.
(i.e. scala supports f-bounded polymorphism)
(note, peter canning, william cook, walter hill, walter olthoff paper:
bounded quantification introduced cardelli , wegner means of typing functions operate uniformly on subtypes of given type.
defined simple "object" model , used bounded quantification type-check functions make sense on objects having specified set of "attributes".
more realistic presentation of object-oriented languages allow objects elements of recursively-defined types.
in context, bounded quantification no longer serves intended purpose. easy find functions makes sense on objects having specified set of methods, cannot typed in cardelli-wegner system.
provide basis typed polymorphic functions in object-oriented languages, introduce f-bounded quantification)
two faces of same coins
there 2 principal forms of abstraction in programming languages:
- parameterization ,
- abstract members.
the first form typical functional languages, whereas second form typically used in object-oriented languages.
traditionally, java supports parameterization values, , member abstraction operations. more recent java 5.0 generics supports parameterization types.
the arguments including generics in scala two-fold:
first, encoding abstract types not straightforward hand. besides loss in conciseness, there problem of accidental name conflicts between abstract type names emulate type parameters.
second, generics , abstract types serve distinct roles in scala programs.
- generics typically used when 1 needs type instantiation, whereas
- abstract types typically used when 1 needs refer abstract type client code.
latter arises in particular in 2 situations: - one might want hide exact definition of type member client code, obtain kind of encapsulation known sml-style module systems.
- or 1 might want override type covariantly in subclasses obtain family polymorphism.
in system bounded polymorphism, rewriting abstract type generics might entail quadratic expansion of type bounds.
update october 2009
abstract type members versus generic type parameters in scala (bill venners)
(emphasis mine)
my observation far abstract type members better choice generic type parameters when:
- you want let people mix in definitions of types via traits.
- you think explicit mention of type member name when being defined code readability.
example:
if want pass 3 different fixture objects tests, you'll able so, you'll need specify 3 types, 1 each parameter. had taken type parameter approach, 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 { // ... }
one other minor difference between abstract type members , generic type parameters when generic type parameter specified, readers of code not see name of type parameter. see line of code:
// type parameter version class mysuite extends fixturesuite[stringbuilder] stringbuilderfixture { // ... }
they wouldn't know name of type parameter specified stringbuilder without looking up. whereas name of type parameter right there in code in abstract type member approach:
// type member version class mysuite extends fixturesuite stringbuilderfixture { type fixtureparam = stringbuilder // ... }
in latter case, readers of code see
stringbuilder
"fixture parameter" type.
still need figure out "fixture parameter" meant, @ least name of type without looking in documentation.
Comments
Post a Comment