360 likes | 523 Vues
A Comparative Study Of Language Support for Generic Programming Oopsla 2003. Roland Garcia Jaakko Jarvi Andrew Lumsdaine Jeremy Siek Jeremiah Wilcock Presented by: Regine Issan. Generics…. What’s the point ? reusable algorithms , reusable data structures
E N D
A Comparative Study Of Language Support for Generic ProgrammingOopsla 2003 • Roland Garcia • Jaakko Jarvi • Andrew Lumsdaine • Jeremy Siek • Jeremiah Wilcock Presented by: Regine Issan
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
Research Results • 8 criterions indicating generics support extended research …
Our Graph Library all we want is: BFS (G g,Vertex s, ColorMap c,Visitor vis)
Iterator element Iter.next() element is associated type What about BFS ReadWriteMap ? Terminology To features understanding associated typessimple 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 Terminology to feature understanding:associated typesgraph library example
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 feature call: BFS (G g, G::vertex s, ColorMap c,Visitor vis) Terminology to features understanding:associated types restriction extended research…
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 concepts multi type concept • concept set restrictions on several types
Terminology: concept refinement • 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: includeJava: extends • EiffelL inheritC#: (:)
Introduction to generics in ML ML Structure ~ OOP Class ~ type ML Signature ~ OOP Interface ~ Concept Structure f1Model = struct type f1_field = int fun calc (x: int ) = x*x end End Signature f1Concept = Sig type f1_field val calc: f1_feild -> f1_feild End Signature S = sig structure f1: f1Concept End Functor makeInstance (Params: S ) = struct fun go x = Params.f1.calc (Params.f1.calc ( x) ) End Structure F= makeInstance ( struct structure f1= f1Model end ) F.go 5 Signature restrict type Represents ML concept Structure meet signature S is abstract type algorithm expressed with abstract type Instantiate algorithm with concrete type (f1Model)
Apple Example: C++ ComparableConceptdocumented no constrainton type parameter //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) Generic algorithm as function template with type parameter Appleimplicitly modelsComparable Implicit instantiation
Comparableconceptas interface with type parameter Apple Example: Java InterfaceComparable<T>{ boolean better(T x); } Class pick { static <T extendsComparable<T>> T go (T a, T b) { if ( a. better (b)) return a; return b; } Class AppleimplementsComparable<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) } } constraint extend a class and implement a set of interfaces Multiple constraints on type parameter Generic algorithmin class method with type parameter Appleexplicitly modelsComparable Implicit instantiation
Comparable concept as Java Apple example: C# constraint No more than one constraint on type parameter (Gyro, not .NET) InterfaceComparable<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 boolbetter(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; } Generic algorithm as Java Apple explicitly models Comparableas in Java Explicit instantiation Programmer specifies type parameters (and associated type parameter)
Apple Example: Eiffel Comparable concept as deferred class with type parameter Deferred classComparable [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; end End End Class AppleinheritComparable [Apple] end Create make Feature make (r: INTEGER) is do rating:= r end better (a :Apple) : BOOLEAN is do Result:= rating < a. rating; end End feature {Apple} rating: INTEGER end Class ROOT_CLASS create main Feature main is local a1, a2, a3 :Apple; picker :Pick [Apple] docreate picker; create a1.make (3); create a2.make(5); a3 :=picker. Go (a1,a2) End end constraint No more than one constraint on type parameter Apple explicitly models Comparable Explicit instantiation
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: yes If 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 Evaluation: retroactive modeling feature support
No Type parameters in generic instantiation avoid verbose code Evaluation: implicit instantiation feature support 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
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 Evaluation: Separate compilation feature support
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& go (const Comparable& x, const Comparable& y) {if ( better (x,y)) …} … go (a1,a2) …
Multiple constraints feature: what do we want ? BFS: G models VertexListGraph & IncidenceGraph multiple constraints on G ?! what if PL don’t’ support ?
Evaluation: Multiple constraints feature support Can you set more than one constraint on a type parameter ? • 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 …
Evaluation: Multiple constraints in ML simple solution : Refinement 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 Signatures Include expressed Concept refinement What is wrong ?!
Evaluation: Multiple constraints in ML workaround when refinement fails – duplicate the structure • 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 End Signature IncidenceGraphSig = Sig Include GraphSig Type edge_t Val out_edges: graph_t -> vertex_t -> edge_t list end Signature VertexListGraphSig = Sig Include GraphSig Val vertices: graph_t -> vertex_t list End Signature BFSSig =Sig Structure G1: InceidenceGraphSig Structure G2: VertexListGraphSig Structure C: ColorMapSig Structure Vis: BFSVisitor Sig Sharing G1 = G2 …. End Sharingcommon nested elements refer the same entity
Evaluation: multiple constraints in ML- workaround when refinement fails result in awkward code Signature BFSSig =Sig Structure G1: InceidenceGraphSig Structure G2: VertexListGraphSig Structure C: ColorMapSig Structure Vis: BFSVisitor Sig Sharing G1 = G2 …. End functor MakeBFS (Params: BFSPSg) =struct fun breadth_first_search graph root visitor map = … end End Structure ALGraph =Struct Datatype graph_t = Data of int * int list Array.array Type vertex_t = int type edge_t = int*int Fun 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 … models both restrictions !
Evaluation: associated type access in C++ 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++using traits GT must have vertex typedef 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, ….) G vertex A.T accessed graph_trait Typename : unknown identifier is considered as type
Evaluation: associated type access in ML So easy: associated types encapsulated within the type signature ColorMapSig = sig type key_t type val_t Val get key_t ->value_t … end Signature BFSSig = Sig Structure Vis: BFSVisitorSig Sturcure G: VertexListGraphAndIncidenceGraph Structure C: ColorMapSig access C.key_t C.val_t when needed End • constraint on associated types: sharing type C.key_t = C.val_t !
Evaluation: associated type accesswhat about Java, C#, Eiffel ? • 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 access in Java adding A.T to interface declaration Vertex associated type in interface parameter list 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);… } Edge associated type in interface parameter list
Evaluation: associated type access in Javareferring interfaces AT in generic method Public class breadth_first_search { Public static < Vertex, Visitorextends BFSVisitor, ColorMapextends ReadWriteMap <Vertex, Integer> Edgeextends GraphEdge<Vertex>, VertexIterator extends Iterator <Vertex>, OutEdgeIteratorextends IIterator<Edge>, G extendsVertexListGraph <Vertex,VertexIterator> , IncidenceGraph <Vertex, Edge, OutEdgeIterator> > void go ( G g, Vertex s, ColorMap c, Visitor vis); } 4 method parameters. 3 associated types specified in interface type list Capture A.T relationships colorMap key is same type as graph vertex S tart vertex is same type as graph vertex
Evaluation: associated type access in Javareferring interfaces AT in implementing classes 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 Java,C#,Eiffel summery 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 encapsulate associated types !!!
Motivation: express relation betwee A.T Evaluation: associated type access ML: encapsulate within structure, sharing C++: 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
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 …
Evaluation: multi type conceptmulti type concept split into several interfaces • 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)
Research Results • criterions to indicate PL generics support