1
A Comparative Study Of Language Support for Generic
ProgrammingOopsla 2003
• Roland Garcia • Jaakko Jarvi• Andrew Lumsdaine• Jeremy Siek • Jeremiah Wilcock
Presented by: Regine Issan
2
Generics…• What’s the point ?
– reusable algorithms , reusable data structures • Expressed using type parameter• No programming language does this right !
• Previous attempts– C++ STL ?!– Java type safe containers ?!– LEDA ?!
• This work:– Generic graph library in 6 PL
http://www.osl.iu.edu/research/comparing
3
Research Results • 8 criterions indicating generics support
C++ Java C# Eiffel ML
multiple constraints
implicit instantiation
retro active modeling
Associated types access
Multi type concepts
separate compilation
Constraints between associated types
extended research …
4
Our Graph Library
all we want is:BFS (G g,Vertex s, ColorMap c,Visitor vis)
5
Terminology To features understanding associated typessimple example• Iterator
element Iter.next()
element is associated type• What about BFS ReadWriteMap ?
6
Terminology to feature understanding:associated types
graph library example• type parametes: G, C, vis• what are G associated types ?
– G models VertexListGraph and IncidenceGraph interfaces• IncidenceGraph { “interface”}
– G::out_edge_iter out_edges (const G&, vertex )
– vertex src (edge, const G& )• VertexListGraph {“interface”}
– G::vertex_iter vertices (const G&)
4 associated types
7
Terminology to features understanding: associated types restriction
BFS (G g, Vertex s, ColorMap c,Visitor vis)Any restrictions ?
C.key type == G.Vertex type G::vertex type == Vertex type
C A.T: { key , value}G A.T : {Vertex, edge, out_edge_iter, vertex_iter }
– Constraint associated types feature C.key type == G.Vertex type
– access associated types featurecall: BFS (G g, G::vertex s, ColorMap c,Visitor vis)
extended research…
8
Terminology to features understanding:concept, model
algorithm restrict type parameters using Concepts • C is a ColorMap
Concept set of requirements on a type or on a set of types • method signatures
– colorMap: value_t get (key_t)• support associated types access
– C.key_t• A.T relationship
– (C.key type == G.Vertex type)» Almost as Interface
A type models a concept by meeting its requirements. • Explicit model: class C implements I• Implicit model: structural conformance
multiple constraints on type parameter– G models vertexListGraph and IncidenceGrpah
conceptsmulti type concept
– concept set restrictions on several types
9
• Concept A is said to refine concepts c1,c2, … if its requirements includes concepts c1,c2, …. Requirements• Usage:
– G models vertexListGraph and IncidenceGrpah concepts– What if P.L doesn’t support multiple constraints on G ?
• Create a single concept from scratch• Or … refine!
– ML: include Java: extends– EiffelL inherit C#: (:)
Terminology: concept refinement
10
Introduction to generics in ML
ML Structure ~ OOP Class ~ typeML Signature ~ OOP Interface ~ Concept
Structure f1Model = structtype f1_field = int fun calc (x: int ) = x*x end
EndSignature f1Concept = Sig
type f1_fieldval calc: f1_feild -> f1_feild
End
Signature S = sigstructure f1: f1Concept
EndFunctor makeInstance (Params: S ) = struct
fun go x = Params.f1.calc (Params.f1.calc ( x) )EndStructure F= makeInstance ( struct structure f1= f1Model end )F.go 5
Structure meet signature Signature restrict typeRepresents ML concept
algorithm expressed with abstract type
Instantiate algorithm with concrete type (f1Model)
S is abstract type
11
Apple Example: C++
//bool better (const T&, const T&)
Template <class Comparable>
const Comparable& go (const Comparable& x, const Comparable& y) {
if ( better (x,y)) return x; return y;
}
Struct Apple {
int rating;
Apple (int r) : rating (r) {}
};
Bool better (const Apple& a, const Apple& b)
{ return b. rating < a. rating; }
Int main (char*[]){
Apple a1(3),a2(5);
Apple& a3 = go (a1,a2)
Comparable Concept documented
Generic algorithm as function template with type
parameter
no constraint on type parameter
Apple implicitly models Comparable
Implicit instantiation
12
Apple Example: Java
Interface Comparable <T> { boolean better (T x); }
Class pick { static <T extends Comparable<T>> T go (T a, T b) { if ( a. better (b)) return a; return b; }
Class Apple implements Comparable<Apple> { Apple (int r) { rating = r; } public boolean better (Apple x) {return x .rating < rating; } Int rating;}
Public class Main() {public static void main (String[] args) {
Apple a1 = new Apple (3); Apple a2 = new Apple (5); Apple a3 = pick. go (a1,s2) }}
Comparable concept as
interface with type parameter
constraintextend a class and implement a set
of interfacesMultiple constraints on type parameter
Apple explicitly models
Comparable
Generic algorithm in class method with type
parameter
Implicit instantiation
13
Apple example: C#
Interface Comparable <T> { bool better (T x); }
Class Pick{
Static T go <T> (T a, T b) where T: Comparable<T> {if (a. better (b)) return a; return b;}
}
Class Apple : Comparable<Apple> { public Apple (int r) {rating = r;}
public bool better (Apple x) { return x .rating < rating; }private int rating;
}
Public class Main_eg {public static int Main (string[] args) {
Apple a1 = new Apple(3); a2 = new Apple(5);
Apple a3 = pick.go <Apple> (a1,a2);
return 0;
}
Comparable concept as Java
constraintNo more than one constraint on type parameter (Gyro,
not .NET)
Apple explicitly models
Comparable as in Java
Generic algorithm as Java
Explicit instantiationProgrammer specifies type
parameters (and associated type parameter)
14
Apple Example: EiffelDeferred class Comparable [T] Feature better (a : T) :BOOLEAN is deferred
end
Class Pick [T -> Comparable [T] ] Feature go (a: T, b: T) is do if a. better (b) Result:=a else Result:= b; endEnd
EndClass Apple inherit Comparable [Apple] end
Create make
Feature make (r: INTEGER) is do rating:= r end
better (a :Apple) : BOOLEAN is do Result:= rating < a. rating; endEndfeature {Apple} rating: INTEGER
endClass ROOT_CLASS
create main Feature main is
local a1, a2, a3 :Apple;
picker :Pick [Apple] do create picker; create a1.make (3); create a2.make(5);
a3 := picker. Go (a1,a2)End
end
Comparable concept as deferred class with type
parameter
constraintNo more than one constraint on
type parameter
Apple explicitly models
Comparable
Explicit instantiation
15
Evaluation: retroactive modeling feature support
• If you build new generic algorithm – T is constrained by completely new concept
• Can T be substituted by existing types ?– Can existing types model the new concept ?
• ML: yesIf you add: Signature newS = sig … end
structures implicitly model newS• Java, C#, Eiffel:
– If you add : Interface newI = { … }no class models it until it’s explicitly declared
C++ Java C# Eiffel ML
Retroactive modeling
{}
No concept
{-} {-} {-} {+}
16
Evaluation: implicit instantiation feature support
No Type parameters in generic instantiation– avoid verbose code
C++ Java C# Eiffel ML
Retro active modeling { } {-} {-} {-} {+}
implicit instantiation {+} {+} {-, Gyro} {-} {-}
C++: go (a1,a2)Java: pick. go (a1,s2)C#: pick. go <Apple> (a1,a2);Eiffel: picker :Pick [Apple]
a3 := picker. Go (a1,a2)
ML: Structure F= calcF10F2
( struct structure f1= f1Model structure f2= f2Model end )
F.go 5
17
Evaluation: Separate compilation feature support
• Can generic algorithm be type checked and compiled independently from its call site ?
– Benefits– catch type errors as early as possible – fast compilation and small executable
type arguments constraints => separate compilation support
C++ Java C# Eiffel ML
Retro active modeling {} {-} {-} {-} {+}
implicit instantiation {+} {+} {-,Gyro} {-} {-}
separate compilation {-} {+} {+} {+} {+}
18
Evaluation:
Separate compilation feature support in C++
• No constraints on type parameter• Pitfalls
– executable size– Type checking against template body , not parameters– Invocation with improper type
• non informative error messages• expose template internals
Template <class Comparable> const Comparable& Template <class Comparable> const Comparable& go (const Comparable& x, const Comparable& y) {if ( better (x,y)) …}go (const Comparable& x, const Comparable& y) {if ( better (x,y)) …}
… … go (a1,a2) …go (a1,a2) …
19
Multiple constraints feature: what do we want ?
BFS: G models VertexListGraph & IncidenceGraph
multiple constraints on G ?!
what if PL don’t’ support ?
20
Evaluation: Multiple constraints feature support
Can you set more than one constraint on a type parameter ?
C++ Java C# Eiffel ML
Retro active modeling {} {-} {-} {-} +
implicit instantiation {+} {+} {-,Gyro} {-} {-}
Separate compilation {-} {+} {+} {+} {-}
multiple constraints {} {+} {-, Gyro} {-} {~}
• C++: no constraints on type parameters …• Java: extend a class, implement a set of interfaces• Eiffel: not supported, build new concept (ie, deferred class)
ML: not as we would want. lets see …
21
Signature GraphSig = Sig
Type graph_t Eqtype vertex_t
End
Signature IncidenceGraphSig =Sig Include GraphSig …end
Signature VertexListGraphSig =Sig Include GraphSig…end
Signature vertexListAndIncidenceGraph =
Sig
Include IncidenceGraphSig
Include VertexListGraphSig
End
Evaluation: Multiple constraints in ML simple solution : Refinement
What is wrong ?!
Signatures Include expressed
Concept refinement
22
• idea:– G is constrained multiple times ? Let it appear multiple times !
• Each time it will be constrained by different concept !Signature GraphSig = Sig
Type graph_t Eqtype vertex_t EndSignature IncidenceGraphSig = Sig
Include GraphSig Type edge_tVal out_edges: graph_t -> vertex_t -> edge_t list
end Signature VertexListGraphSig = Sig
Include GraphSigVal vertices: graph_t -> vertex_t list
End
Signature BFSSig =SigStructure G1: InceidenceGraphSigStructure G2: VertexListGraphSigStructure C: ColorMapSigStructure Vis: BFSVisitor SigSharing G1 = G2 ….
End
Evaluation: Multiple constraints in ML workaround when refinement fails – duplicate the structure
Sharing common nested elements refer the same
entity
23
Signature BFSSig =SigStructure G1: InceidenceGraphSigStructure G2: VertexListGraphSigStructure C: ColorMapSigStructure Vis: BFSVisitor SigSharing G1 = G2 ….
Endfunctor MakeBFS (Params: BFSPSg) =struct
fun breadth_first_search graph root visitor map = … endEndStructure ALGraph =Struct
Datatype graph_t = Data of int * int list Array.arrayType vertex_t = int type edge_t = int*intFun out_edges Data(n,g) vertex = ….Fun vertices Data(n,g) = ….
End;
Structure BFS = MakeBFS ( struct Structure G1 = ALGraph Structure G2 = ALGraph Structure C = ALGColorMap Structure Vis = VisitImpl End)
BFS.breadth_first_search …
Evaluation: multiple constraints in ML- workaround when refinement fails result in awkward code
models both restrictions !
24
Look at BFS generic algorithm :
template <class G, Class C, Class Vis>
void breadth_first_search (const G& graph,
????? sourceNode, C colorMap, Vis visitor);
Is it possible to express that ????? Is graph node type ?
traits + typedefs
just another class template
provide Compile time A.T access
Evaluation: associated type access in C++
25
Class AdjacencyList { //models IncidenceGraph and vertexListGraph Public: Typedef int vertex; … }
Template <typename G>Struct graph_traits { typedef G::vertex vertex; … }}
template <class G, Class C, Class Vis>void breadth_first_search (const G& graph,
typename graph_traits<G> :: vertex sourceNode, C colorMap, Vis visitor);
AdjacencyList g; … Breadth_first_search (g,0, ….)
Evaluation: associated type access in C++ using traits
GT must have vertex typedef
G vertex A.T accessed graph_trait
Typename : unknown identifier is considered as type
26
So easy: associated types encapsulated within the type
signature ColorMapSig = sig type key_t type val_t Val get key_t ->value_t … endSignature BFSSig = Sig
Structure Vis: BFSVisitorSig Sturcure G: VertexListGraphAndIncidenceGraph Structure C: ColorMapSig
access C.key_t C.val_t when neededEnd– constraint on associated types:
sharing type C.key_t = C.val_t !
Evaluation: associated type access in ML
27
• Ideally , associated are encapsulated within the type• ML:
– Structures naturally encapsulate types
• C :– Force encapsulation using typedefs
• Java,C#,Eiffel – Classes/interfaces cant encapsulate types
• only methods and member variables
“Solution”: add associated types to the type parameter list !!!
lets see …
Evaluation: associated type accesswhat about Java, C#, Eiffel ?
28
public interface GraphEdge <Vertex> {
Vertex source(); Vertex target();
}
Public interface VertexListGraph
<Vertex, VertexIterator extendIterator<Vertex>> {
VertexIterator vertices();…
}
public interface IncidenceGraph
<Vertex, Edge, OutEdgeIterator extends Iterator<Edge>>{
OutEdgeIterator out_edges(Vertex v);…
}
Evaluation: associated type access in Java adding A.T to interface declaration
Vertex associated type in interface parameter list
Edge associated type in interface parameter list
29
Public class breadth_first_search { Public static <
Vertex, Visitor extends BFSVisitor, ColorMap extends ReadWriteMap <Vertex, Integer>
Edge extends GraphEdge<Vertex>, VertexIterator extends Iterator <Vertex>, OutEdgeIterator extends IIterator<Edge>,
G extends VertexListGraph < Vertex, VertexIterator> ,
IncidenceGraph <Vertex, Edge, OutEdgeIterator> > void go ( G g, Vertex s, ColorMap c, Visitor vis); }
Evaluation: associated type access in Java
referring interfaces AT in generic method
4 method parameters.3 associated types
specified in interface type list
Capture A.T relationships colorMap key is same type as graph
vertexS tart vertex is same type as graph
vertex
30
Public interface VertexListGraph<Vertex, VertexIterator extendIterator<Vertex>> { VertexIterator vertices();}
public interface IncidenceGraph<Vertex, Edge, OutEdgeIterator extends Iterator<Edge>>{
OutEdgeIterator out_edges(Vertex v);}public class adjacency_list
implements VertexListGraph < Integer, Iterator<Integer> >, IncidenceGraph < Integer, simpleEdge<integer>, Iterator<simpleEdge<integer> > > { …}
breadth_first_search.go (g, src,color_map,visitor)
Evaluation: associated type access in Javareferring interfaces AT in implementing classes
31
A.T as part of type parameters list ?!• We can access then
• within generic algorithm• we must access them every time we refer a concept
– Even if algorithm does not use it – lengthy code – Constraints repetition– Breaking encapsulation
Expose potentially helper types
Evaluation: associated type access in Java,C#,Eiffelsummery
encapsulate associated types !!!
32
Evaluation: associated type access
• Motivation: express relation betwee A.T
C++ Java C# Eiffel ML
associated types access
{+} {~} {~} {~} {+}
ML: encapsulate within structure, sharingC++: encapsulated within class,
traits used to access them captures associated types relations
Java,c#,eiffe: A.T explicitly specified in type parameter list of a concept
33
Evaluation: multi type concept• Can one concept constrain several types ?• ML
– Signature • Encapsulate structures and methods
• OOP: – Interface
• constrains a single class
OOP concepts are not as strong as concepts ! , why ? Lets see …
C++ Java C# Eiffel ML
Multi type concepts
{-} {-} {-} {-} {+}
34
• Algorithm ConceptA: { Vector<V> mult Scalar<S> => Vector<V>
Scalar<S> mult Vector<V> => Vector<V>}
• Oop interpretation– Vector<V> has:
• Vector<V> mult (Scalar<S>)
• Scalar<S> has:• Vector<V> mult (Vector<V>)
two interfaces required to express ConceptA ! interfaces cant express multi types concept !
– Restrict implementing class only, not multiple classes
What if conceptA is refined ? (2^n interfaces)
Evaluation: multi type concept multi type concept split into several interfaces
35
Research Results • criterions to indicate PL generics support
C++ Java C# Eiffel ML
multiple constraints {} {+} {-,Gyro} {-} {~}
implicit instantiation {+} {+} {-} {-} {-}
separate compilation {-} {+} {+} {+} {+}
retro active modeling {} {-} {-} {-} {+}
Associated types access
{+} {~} {~} {~} {+}
Multi type concepts {} {-} {-} {-} {+}
36
Questions !?