generics
play

Generics Akim Demaille, Etienne Renault, Roland Levillain March 29, - PowerPoint PPT Presentation

Generics Akim Demaille, Etienne Renault, Roland Levillain March 29, 2020 TYLA Generics March 29, 2020 1 / 54 Table of Contents Some definitions 1 Some history 2 Some Paradigms 3 TYLA Generics March 29, 2020 2 / 54 Problem Statement


  1. Implementation of parameterized modules in CLU Notion of instantiation : binding a module and its parameter(s) Syntax: module [ parameter ] Dynamic instantiation of parameterized modules. For a given module, each distinct set of parameters is represented by a (run-time) object. Instantiated modules derived from a non-instantiated object module. Common code is shared. Pros and cons of run- or load-time binding: Pros No combinatorial explosion due to systematic code generation (as with C++ templates). Cons Lack of static instantiation context means less opportunities to optimize. TYLA Generics March 29, 2020 14 / 54

  2. TYLA Generics March 29, 2020 15 / 54

  3. Table of Contents Some definitions 1 Some history 2 CLU Ada 83 C++ Some Paradigms 3 TYLA Generics March 29, 2020 16 / 54

  4. Genericity in Ada 83 Introduced with the generic keyword generic type T is private ; procedure swap ( x , y : in out T ) is t : T begin t : = x ; x : = y ; y : = t ; end swap ; -- Explicit instantiations. procedure int swap is new swap ( INTEGER ) ; procedure str swap is new swap ( STRING ) ; Example of unconstrained genericity. Instantiation of generic clauses is explicit (no implicit instantiation as in C++). TYLA Generics March 29, 2020 17 / 54

  5. Generic packages in Ada 83 generic type T is private ; package STACKS is type STACK ( s i z e : POSITIVE ) is record space : array ( 1 . . s i z e ) of T ; index : NATURAL end record ; function empty ( s : in STACK ) return BOOLEAN ; procedure push ( t : in T ; s : in out STACK ) ; procedure pop ( s : in out STACK ) ; function top ( s : in STACK ) return T ; end STACKS ; package INT STACKS is new STACKS ( INTEGER ) ; package STR STACKS is new STACKS ( STRING ) ; TYLA Generics March 29, 2020 18 / 54

  6. Constrained Genericity in Ada 83 Constrained genericity imposes restrictions on generic types: generic type T is private ; with function ” < =” ( a , b : T ) return BOOLEAN is <> ; function minimum ( x , y : T ) return T is begin if x < = y then return x ; else return y ; end if ; end minimum ; TYLA Generics March 29, 2020 19 / 54

  7. Constrained Genericity in Ada 83 Constrained genericity imposes restrictions on generic types: generic type T is private ; with function ” < =” ( a , b : T ) return BOOLEAN is <> ; function minimum ( x , y : T ) return T is begin if x < = y then return x ; else return y ; end if ; end minimum ; Constraints are only of syntactic nature (no formal constraints expressing semantic assertions) TYLA Generics March 29, 2020 19 / 54

  8. Constrained Genericity in Ada 83: Instantiation Instantiation can be fully qualified function T1 minimum is new minimum ( T1 , T 1 l e ) ; TYLA Generics March 29, 2020 20 / 54

  9. Constrained Genericity in Ada 83: Instantiation Instantiation can be fully qualified function T1 minimum is new minimum ( T1 , T 1 l e ) ; or take advantage of implicit names: function int minimum is new minimum ( INTEGER ) ; Here, the comparison function is already known as < = . TYLA Generics March 29, 2020 20 / 54

  10. More Genericity Examples in Ada 83 Interface (“specification”): -- matrices.ada generic type T is private ; zero : T ; unity : T ; with function ”+” ( a , b : T ) return T is <> ; with function ” ∗ ” ( a , b : T ) return T is <> ; package MATRICES is type MATRIX ( l i n e s , columns : POSITIVE ) is array ( 1 . . l i n e s , 1 . . columns ) of T ; function ”+” (m1 , m2 : MATRIX ) return MATRIX ; function ” ∗ ” (m1 , m2 : MATRIX ) return MATRIX ; end MATRICES ; TYLA Generics March 29, 2020 21 / 54

  11. More Genericity Examples in Ada 83 Instantiations: package FLOAT MATRICES is new MATRICES ( FLOAT , 0 . 0 , 1 . 0 ) ; TYLA Generics March 29, 2020 22 / 54

  12. More Genericity Examples in Ada 83 Instantiations: package FLOAT MATRICES is new MATRICES ( FLOAT , 0 . 0 , 1 . 0 ) ; package BOOL MATRICES is new MATRICES (BOOLEAN, f a l s e , true , ” or ” , ” and ” ) ; TYLA Generics March 29, 2020 22 / 54

  13. More Genericity Examples in Ada 83 Implementation (“body”): -- matrices.adb package body MATRICES is function ” ∗ ” (m1 , m2 : MATRIX ) is r e s u l t : MATRIX (m1’ l i n e s , m2’ columns ) begin if m1’ columns /= m2’ l i n e s then raise INCOMPATIBLE SIZES ; end if ; for i in m1’ RANGE ( 1 ) loop for j in m2’ RANGE ( 2 ) loop r e s u l t ( i , j ) : = zero ; for k in m1’ RANGE ( 2 ) loop r e s u l t ( i , j ) : = r e s u l t ( i , j ) + m1 ( i , k ) ∗ m2 ( k , j ) ; end loop ; end loop ; end loop ; end ” ∗ ” ; -- Other declarations... end MATRICES ; TYLA Generics March 29, 2020 23 / 54

  14. Table of Contents Some definitions 1 Some history 2 CLU Ada 83 C++ Some Paradigms 3 TYLA Generics March 29, 2020 24 / 54

  15. A History of C++ Templates Initial motivation: provide parameterized containers. TYLA Generics March 29, 2020 25 / 54

  16. A History of C++ Templates Initial motivation: provide parameterized containers. Previously, macros were used to provide such containers (in C and C with classes). TYLA Generics March 29, 2020 25 / 54

  17. A History of C++ Templates Initial motivation: provide parameterized containers. Previously, macros were used to provide such containers (in C and C with classes). Many limitations, inherent to the nature of macros: TYLA Generics March 29, 2020 25 / 54

  18. A History of C++ Templates Initial motivation: provide parameterized containers. Previously, macros were used to provide such containers (in C and C with classes). Many limitations, inherent to the nature of macros: ◮ Poor error messages referring to the code writen by cpp , not by the programmer. TYLA Generics March 29, 2020 25 / 54

  19. A History of C++ Templates Initial motivation: provide parameterized containers. Previously, macros were used to provide such containers (in C and C with classes). Many limitations, inherent to the nature of macros: ◮ Poor error messages referring to the code writen by cpp , not by the programmer. ◮ Need to instantiate templates once per compile unit, manually . TYLA Generics March 29, 2020 25 / 54

  20. A History of C++ Templates Initial motivation: provide parameterized containers. Previously, macros were used to provide such containers (in C and C with classes). Many limitations, inherent to the nature of macros: ◮ Poor error messages referring to the code writen by cpp , not by the programmer. ◮ Need to instantiate templates once per compile unit, manually . ◮ No support for recurrence. TYLA Generics March 29, 2020 25 / 54

  21. Simulating parameterized types with macros #define VECTOR( T ) v e c t o r ## T #define GEN VECTOR( T ) \ class VECTOR( T ) { \ public : \ typedef T value type ; \ VECTOR( T ) ( ) { /* ... */ } \ VECTOR( T ) ( int i ) { /* ... */ } \ value type& operator [ ] ( int i ) { /* ... */ } \ /* ... */ \ } // Explicit instantiations. GEN VECTOR( int ) ; GEN VECTOR( long ) ; int main ( ) { VECTOR( int ) v i ; VECTOR( long ) v l ; } TYLA Generics March 29, 2020 26 / 54

  22. A History of C++ Templates (cont.) Introduction of a template mechanism around 1990, later refined (1993) before the standardization of C++ in 1998. TYLA Generics March 29, 2020 27 / 54

  23. A History of C++ Templates (cont.) Introduction of a template mechanism around 1990, later refined (1993) before the standardization of C++ in 1998. Class templates. TYLA Generics March 29, 2020 27 / 54

  24. A History of C++ Templates (cont.) Introduction of a template mechanism around 1990, later refined (1993) before the standardization of C++ in 1998. Class templates. Function templates (and member function templates). TYLA Generics March 29, 2020 27 / 54

  25. A History of C++ Templates (cont.) Introduction of a template mechanism around 1990, later refined (1993) before the standardization of C++ in 1998. Class templates. Function templates (and member function templates). Automatic deduction of parameters of template functions. TYLA Generics March 29, 2020 27 / 54

  26. A History of C++ Templates (cont.) Introduction of a template mechanism around 1990, later refined (1993) before the standardization of C++ in 1998. Class templates. Function templates (and member function templates). Automatic deduction of parameters of template functions. Type and non-type template parameters. TYLA Generics March 29, 2020 27 / 54

  27. A History of C++ Templates (cont.) Introduction of a template mechanism around 1990, later refined (1993) before the standardization of C++ in 1998. Class templates. Function templates (and member function templates). Automatic deduction of parameters of template functions. Type and non-type template parameters. No explicit constraints on parameters. TYLA Generics March 29, 2020 27 / 54

  28. A History of C++ Templates (cont.) Introduction of a template mechanism around 1990, later refined (1993) before the standardization of C++ in 1998. Class templates. Function templates (and member function templates). Automatic deduction of parameters of template functions. Type and non-type template parameters. No explicit constraints on parameters. Implicit (automatic) template instantiation (though explicit instantiation is still possible). TYLA Generics March 29, 2020 27 / 54

  29. A History of C++ Templates (cont.) Introduction of a template mechanism around 1990, later refined (1993) before the standardization of C++ in 1998. Class templates. Function templates (and member function templates). Automatic deduction of parameters of template functions. Type and non-type template parameters. No explicit constraints on parameters. Implicit (automatic) template instantiation (though explicit instantiation is still possible). Full (classes, functions) and partial (classes) specializations of templates definitions. TYLA Generics March 29, 2020 27 / 54

  30. A History of C++ Templates (cont.) Introduction of a template mechanism around 1990, later refined (1993) before the standardization of C++ in 1998. Class templates. Function templates (and member function templates). Automatic deduction of parameters of template functions. Type and non-type template parameters. No explicit constraints on parameters. Implicit (automatic) template instantiation (though explicit instantiation is still possible). Full (classes, functions) and partial (classes) specializations of templates definitions. A powerful system allowing metaprogramming techniques (though not designed for that in the first place!) TYLA Generics March 29, 2020 27 / 54

  31. Class Templates template < typename T > class v e c t o r { public : typedef T value type ; v e c t o r ( ) { /* ... */ } v e c t o r ( int i ) { /* ... */ } value type& operator [ ] ( int i ) { /* ... */ } /* ... */ } ; // No need for explicit template instantiations. int main ( ) { vector < int > v i ; vector < long > v l ; } TYLA Generics March 29, 2020 28 / 54

  32. Function Templates Natural in a language with non-member functions (such as C++). template < typename T > void swap ( T& a , T& b ) { T tmp = a ; a = b ; b = tmp ; } TYLA Generics March 29, 2020 29 / 54

  33. Function Templates Natural in a language with non-member functions (such as C++). template < typename T > void swap ( T& a , T& b ) { T tmp = a ; a = b ; b = tmp ; } Class templates can make up for the lack of generic functions in most uses cases (through fonctor ). TYLA Generics March 29, 2020 29 / 54

  34. Function Templates Natural in a language with non-member functions (such as C++). template < typename T > void swap ( T& a , T& b ) { T tmp = a ; a = b ; b = tmp ; } Class templates can make up for the lack of generic functions in most uses cases (through fonctor ). Eiffel does not feature generic function at all. TYLA Generics March 29, 2020 29 / 54

  35. Function Templates Natural in a language with non-member functions (such as C++). template < typename T > void swap ( T& a , T& b ) { T tmp = a ; a = b ; b = tmp ; } Class templates can make up for the lack of generic functions in most uses cases (through fonctor ). Eiffel does not feature generic function at all. Java and C-sharp provide only generic member functions. TYLA Generics March 29, 2020 29 / 54

  36. Specialization of Template Definitions Idea: provide another definition for a subset of the parameters. TYLA Generics March 29, 2020 30 / 54

  37. Specialization of Template Definitions Idea: provide another definition for a subset of the parameters. Motivation: provide (harder,) beter, faster, stronger implementations for a given template class or function. TYLA Generics March 29, 2020 30 / 54

  38. Specialization of Template Definitions Idea: provide another definition for a subset of the parameters. Motivation: provide (harder,) beter, faster, stronger implementations for a given template class or function. Example: boolean vector has its own definition, different from type T vector TYLA Generics March 29, 2020 30 / 54

  39. Specialization of Template Definitions Idea: provide another definition for a subset of the parameters. Motivation: provide (harder,) beter, faster, stronger implementations for a given template class or function. Example: boolean vector has its own definition, different from type T vector Mechanism close to function overloading in spirit, but distinct. TYLA Generics March 29, 2020 30 / 54

  40. Alexander Alexandrovich Stepanov (Nov. 16, 1950) TYLA Generics March 29, 2020 31 / 54

  41. Alexander Alexandrovich Stepanov (Nov. 16, 1950) Алекса́ндр Алекса́ндрович Степа́нов TYLA Generics March 29, 2020 32 / 54

  42. The Standard Template Library (STL) A library of containers, iterators, fundamental algorithms and tools, using C++ templates. TYLA Generics March 29, 2020 33 / 54

  43. The Standard Template Library (STL) A library of containers, iterators, fundamental algorithms and tools, using C++ templates. Designed by Alexander Stepanov at HP. TYLA Generics March 29, 2020 33 / 54

  44. The Standard Template Library (STL) A library of containers, iterators, fundamental algorithms and tools, using C++ templates. Designed by Alexander Stepanov at HP. The STL is not the Standard C++Library (nor is one a subset of the other) although most of it is part of the standard TYLA Generics March 29, 2020 33 / 54

  45. The Standard Template Library (STL) A library of containers, iterators, fundamental algorithms and tools, using C++ templates. Designed by Alexander Stepanov at HP. The STL is not the Standard C++Library (nor is one a subset of the other) although most of it is part of the standard Introduces the notion of concept : a set of syntactic and semantic requirements over one (or several) types. TYLA Generics March 29, 2020 33 / 54

  46. The Standard Template Library (STL) A library of containers, iterators, fundamental algorithms and tools, using C++ templates. Designed by Alexander Stepanov at HP. The STL is not the Standard C++Library (nor is one a subset of the other) although most of it is part of the standard Introduces the notion of concept : a set of syntactic and semantic requirements over one (or several) types. But the language does not enforce them. TYLA Generics March 29, 2020 33 / 54

  47. The Standard Template Library (STL) A library of containers, iterators, fundamental algorithms and tools, using C++ templates. Designed by Alexander Stepanov at HP. The STL is not the Standard C++Library (nor is one a subset of the other) although most of it is part of the standard Introduces the notion of concept : a set of syntactic and semantic requirements over one (or several) types. But the language does not enforce them. Initially planned as a language extension in the C++11/14/17 standard... TYLA Generics March 29, 2020 33 / 54

  48. The Standard Template Library (STL) A library of containers, iterators, fundamental algorithms and tools, using C++ templates. Designed by Alexander Stepanov at HP. The STL is not the Standard C++Library (nor is one a subset of the other) although most of it is part of the standard Introduces the notion of concept : a set of syntactic and semantic requirements over one (or several) types. But the language does not enforce them. Initially planned as a language extension in the C++11/14/17 standard... ...but abandonned shortly before the standardization. :-( TYLA Generics March 29, 2020 33 / 54

  49. Example template < typename T > concept Hashable = r e q u i r e s ( T a ) { { std : : hash < T > {} (a ) } − > std : : c o n v e r t i b l e t o < std : : s i z e t > ; } ; struct meow {} ; < Hashable T > template void f ( T ) ; // constrained C++20 function template TYLA Generics March 29, 2020 34 / 54

  50. Table of Contents Some definitions 1 Some history 2 Some Paradigms 3 TYLA Generics March 29, 2020 35 / 54

  51. Problem Statement How to implement Generics ? TYLA Generics March 29, 2020 36 / 54

  52. Table of Contents Some definitions 1 Some history 2 Some Paradigms 3 Boxing Monomorphization TYLA Generics March 29, 2020 37 / 54

  53. Boxing: main idea Put everything in uniform ”boxes” so that they all act the same way TYLA Generics March 29, 2020 38 / 54

  54. Boxing: main idea Put everything in uniform ”boxes” so that they all act the same way The data structure only handles pointers Wideley used strategy: C: use void pointers + dynamic cast Go: interface Java (pre-generics): Objects Objective-C (pre-generics): id TYLA Generics March 29, 2020 38 / 54

  55. Boxing: main idea Put everything in uniform ”boxes” so that they all act the same way The data structure only handles pointers Pointers to different types act the same way Wideley used strategy: C: use void pointers + dynamic cast Go: interface Java (pre-generics): Objects Objective-C (pre-generics): id TYLA Generics March 29, 2020 38 / 54

  56. Boxing: main idea Put everything in uniform ”boxes” so that they all act the same way The data structure only handles pointers Pointers to different types act the same way … so the same code can deal with all data types! Wideley used strategy: C: use void pointers + dynamic cast Go: interface Java (pre-generics): Objects Objective-C (pre-generics): id TYLA Generics March 29, 2020 38 / 54

  57. Go example type Stack struct { values [ ] i n t e r f a c e {} } func ( t h i s ∗ Stack ) Push ( value i n t e r f a c e {} ) { t h i s . values = append ( t h i s . values , value ) } TYLA Generics March 29, 2020 39 / 54

  58. Pro/cons with the boxing approach Pros: Easy to implement in (any) language Cons: Casts for every read/write in the structure ⇒ runtime overhead! = Error-prone: type-checking ⇒ No mechanism to prevent us puting elements of = different types into the structure TYLA Generics March 29, 2020 40 / 54

  59. Type-erased boxed generics Idea add generics functionality to the type system BUT use the basic boxing method exactly as before at runtime. TYLA Generics March 29, 2020 41 / 54

  60. Type-erased boxed generics Idea add generics functionality to the type system BUT use the basic boxing method exactly as before at runtime. → This approach is ofen called type erasure , because the types in the generics system are ”erased” and all become the same type TYLA Generics March 29, 2020 41 / 54

  61. Type-erased boxed generics Idea add generics functionality to the type system BUT use the basic boxing method exactly as before at runtime. → This approach is ofen called type erasure , because the types in the generics system are ”erased” and all become the same type Java and Objective-C both started out with basic boxing … but add features for generics with type erasure TYLA Generics March 29, 2020 41 / 54

  62. Java Example Without Generics (pre Java 4.0) Throws java.lang.ClassCastException L i s t v = new A r r a y L i s t ( ) ; v . add ( ” t e s t ” ) ; // A String that cannot be cast to an Integer I n t e g e r i = ( I n t e g e r ) v . get ( 0 ) ; // Run time error TYLA Generics March 29, 2020 42 / 54

  63. Java Example Without Generics (pre Java 4.0) Throws java.lang.ClassCastException L i s t v = new A r r a y L i s t ( ) ; v . add ( ” t e s t ” ) ; // A String that cannot be cast to an Integer I n t e g e r i = ( I n t e g e r ) v . get ( 0 ) ; // Run time error With Generics Fails at compile time List < String > v = new ArrayList < String > ( ) ; v . add ( ” t e s t ” ) ; I n t e g e r i = v . get ( 0 ) ; // (type error) compilation-time error TYLA Generics March 29, 2020 42 / 54

  64. Todo Wildcard? TYLA Generics March 29, 2020 43 / 54

  65. Inferred boxed generics with a uniform representation Problem with simple boxing In the previous approach, generic data structures cannot hold primitive types! TYLA Generics March 29, 2020 44 / 54

  66. Inferred boxed generics with a uniform representation Problem with simple boxing In the previous approach, generic data structures cannot hold primitive types! Ocaml’s Solution Uniform representation where there are no primitive types that requires an additional boxing allocation ! TYLA Generics March 29, 2020 44 / 54

  67. Inferred boxed generics with a uniform representation (cont’d) Ocaml’s apporach: TYLA Generics March 29, 2020 45 / 54

  68. Inferred boxed generics with a uniform representation (cont’d) Ocaml’s apporach: no additional boxing allocation (like int needing to be turned into an Integer TYLA Generics March 29, 2020 45 / 54

  69. Inferred boxed generics with a uniform representation (cont’d) Ocaml’s apporach: no additional boxing allocation (like int needing to be turned into an Integer everything is either already boxed or represented by a pointer-sized integer ⇒ everything is one machine word = TYLA Generics March 29, 2020 45 / 54

Recommend


More recommend