Download presentation
Presentation is loading. Please wait.
Published byBrittany Arnold Modified over 8 years ago
1
5th MaCS Debrecen 2004 1 On the Turing-Completeness of Generative Metaprograms Zoltán Porkoláb, István Zólyomi {gsd|scamel}@elte.hu Dept. of Programming Languages and Compilers Eotvos University, Budapest
2
25th MaCSDebrecen 2004 Agenda I always knew C++ templates were the work of the Devil, and now I'm sure... - Cliff Click cited by Todd Veldhuisen Generative program constructions Metaprograms Power of generative metaprograms Sample usages Open questions
3
35th MaCSDebrecen 2004 Generative constructions Widely used in modern programming languages: Smalltalk, Lisp, other functional langs. Eiffel ADA generics C++ templates Java generics: Pizza, GJ, Java 1.5 C#: soon
4
45th MaCSDebrecen 2004 Why generics? Conventional techniques are working only for complete types. int max( int a, int b) { if ( a > b ) return a; else return b; if ( a > b ) return a; else return b;} double max( double a, double b) { if ( a > b ) return a; else return b; if ( a > b ) return a; else return b;}Etc… class date { //… //… }; date d = max ( d1, d2);
5
55th MaCSDebrecen 2004 Preprocessor Macro? Ada generics : "a restricted form of context-sensitive macro facility" C++ templates: "a clever kind of macro that obeys the scope, naming, and type rules of C++" #define MAX(a,b) a > b ? a : b Works, because a macro is - typeless. Processed not by the compiler, therefore there are a number of "secondary effect": MAX( x, y)*2 x > y ? x : y*2 x > y ? x : y*2 MAX( ++x, y) ++x > y ? ++x : y
6
65th MaCSDebrecen 2004 Generative constructions void swap( int& x, int& y) void swap( int& x, int& y) { int temp = x; // !! how to detect type of x? int temp = x; // !! how to detect type of x? x = y; y = temp; x = y; y = temp; } Does not works: a macro is - typeless. We need a facility to use type parameters. template void swap( T& x, T& y) { T temp = x; x = y; y = temp; } Template depends only on the properties that is actually used Does not require different types used as arguments to be explicitly related. In particular, the argument types used as a template need not be from a single inheritance hierarchy.
7
75th MaCSDebrecen 2004 C++ Function Templates 1. Template is not a single function Rather a schema to instantiate functions on request template T max( T a, T b) { if ( a > b ) return a; if ( a > b ) return a; else return b; else return b;} int i = 3, j = 6, k; k = max(i,j); double x = 3.14, y = 4.15, z; z = max(x,y); Parameter deduction Template instantiation
8
85th MaCSDebrecen 2004 C++ Function Templates 2. Instantiation in compile-time Then strong type system rules are applied int i = 3; double y = 3.14, z; z = max(i,y); template T max( T a, S b) { if ( a > b ) return a; if ( a > b ) return a; else return b; else return b;} z == 3; No deduction on return type No runtime information could be used
9
95th MaCSDebrecen 2004 C++ Function Templates 3. Explicit specialization int i = 3; double y = 3.14, z; template template R max( T a, S b) { if ( a > b ) return a; if ( a > b ) return a; else return b; else return b;} z = max (i,y); Template overloading
10
105th MaCSDebrecen 2004 C++ Function Templates 4. User specialization const char *s1 = “Hello”; const char *s2 = “world”; template <> const char * max( const char *a, const char *b) { if ( strcmp(a,b) < 0 ) return a; if ( strcmp(a,b) < 0 ) return a; else return b; else return b;} The compiler selects the most specific matching type cout << max (4,5); cout (3.14,’6’); cout << max (“this”, “greater”);
11
115th MaCSDebrecen 2004 C++ Class Templates 1. Similar way template class matrix { public: matrix( int i, int j ); matrix( int i, int j ); matrix( const matrix &other) matrix( const matrix &other) ~matrix(); ~matrix(); matrix& operator=( const matrix &other); matrix& operator=( const matrix &other);private: vector v; vector v;}; Created always with explicit specialisation matrix m(4,5);
12
125th MaCSDebrecen 2004 C++ Class Templates 2. User specialization template <> class matrix template <> class matrix { public: matrix( int i, int j ); matrix( int i, int j ); matrix( const matrix &other) matrix( const matrix &other) ~matrix(); ~matrix(); matrix& operator=( const matrix &other); matrix& operator=( const matrix &other);private: a_better_representation v; a_better_representation v;}; Used the same way matrix m(4,5);
13
135th MaCSDebrecen 2004 C++ Class Templates 3. Partial specialization template class C { //... //... }; template class C template class C { //... //... }; The most specific matching will be applied C a; C b;
14
145th MaCSDebrecen 2004 C++ Templates The C++ templates were first implemented in the early ’90s Accepted as part of the ANSI/ISO in 1994 Erwin Unruh: 1994 unruh.cpp 30: conversion from enum to D requested
15
155th MaCSDebrecen 2004 Power of C++ templates The C++ templates are Turing-complete The Compiler “executes” template metaprograms The result is a non-templated program executed in “run-time” In 1966 Böhm and Jacopini proved: Turing machine implementation conditional and looping constructions Turing machine implementation conditional and looping constructions
16
165th MaCSDebrecen 2004 The Factorial example int factorial( int n) { return (n==0) ? 1 : n*factorial(n-1); return (n==0) ? 1 : n*factorial(n-1);} int main() { cout << factorial(15) << endl; cout << factorial(15) << endl; return 0; return 0;} template struct Factorial { enum { value = N * Factorial ::value }; enum { value = N * Factorial ::value };}; template <> struct Factorial { enum { value = 1 }; enum { value = 1 };}; int main() { const int fact5 = Factorial ::value; const int fact5 = Factorial ::value; std::cout << fact5 << endl; std::cout << fact5 << endl; return 0; return 0;}
17
175th MaCSDebrecen 2004 Conditional statement template template struct IF { typedef Then RET; typedef Then RET;}; template template struct IF struct IF { typedef Else RET; typedef Else RET;}; template template IF ::RET max(T t, S s) { if (t > s) return t; if (t > s) return t; else return s; else return s;}
18
185th MaCSDebrecen 2004 Higher order metaprograms accumulate(n,f) := f(0) + f(1) +... + f(n) template class F> struct Accumulate { enum { RET = Accumulate ::RET + F ::RET }; enum { RET = Accumulate ::RET + F ::RET };}; template class F> struct Accumulate template class F> struct Accumulate { enum { RET = F ::RET }; enum { RET = F ::RET };}; template struct Square { enum { RET = n*n }; enum { RET = n*n };}; cout ::RET ::RET << endl;
19
195th MaCSDebrecen 2004 Programs vs. Metaprograms Function (runtime) Data VariableAssignmentConditionLoopClass Type and constant Symbolic names Const initialization enumerated values enumerated valuesRecursion
20
205th MaCSDebrecen 2004 Generative Metaprograms 1. metaprogramming: writing programs that represent and manipulate other programs or themselves (ie:reflection). Metaprograms are programs about programs. introspection: the ability of a program to observe its own state the ability of a program to observe its own state intercession: the ability to modify its own state the ability to modify its own state Open compilers: transformations on AST Hygenic macros Two level languages: Aspect J
21
215th MaCSDebrecen 2004 Generative Metaprograms 2. Dynamic languages (Smalltalk, Lisp, etc.) high level reflection Smalltalk: classes are objects of metaobjects methods, execution stack, etc. are represented by objects high level reflection Smalltalk: classes are objects of metaobjects methods, execution stack, etc. are represented by objectsJava provides lower level reflection C++ RTTI much lower level: (typeid)
22
225th MaCSDebrecen 2004 Main areas Expression templates Static interface checking Concept cheking Extend existing type system ???
23
235th MaCSDebrecen 2004 Expression templates Improve efficiency of programs Save space and / or time Keep the code correctly organized Supercomputing, numerical computing
24
245th MaCSDebrecen 2004 Expression templates Array a, b, c, d, e; // Object-oriented way of a = b + c + d + e double* _t1 = new double[N]; for ( int i=0; i<N; ++i) _t1[i] = b[i] + c[i]; double* _t2 = new double[N]; for ( int i=0; i<N; ++i) _t2[i] = _t1[i] + d[i]; double* _t3 = new double[N*M]; for ( int i=0; i<N; ++i) _t3[i] = _t2[i] + e[i]; for ( int i=0; i<N; ++i) a[i] = _t3[i]; delete [] _t3; delete [] _t2; delete [] _t1; // Fortran like solution: for ( int i=0; i<N; ++i) a[i] = b[i] + c[i] + d[i] + e[i];
25
255th MaCSDebrecen 2004 Static interface cheking Array a, b, c, d, e; // Object-oriented way of a = b + c + d + e double* _t1 = new double[N]; for ( int i=0; i<N; ++i) _t1[i] = b[i] + c[i]; double* _t2 = new double[N]; for ( int i=0; i<N; ++i) _t2[i] = _t1[i] + d[i]; double* _t3 = new double[N*M]; for ( int i=0; i<N; ++i) _t3[i] = _t2[i] + e[i]; for ( int i=0; i<N; ++i) a[i] = _t3[i]; delete [] _t3; delete [] _t2; delete [] _t1; // Fortran like solution: for ( int i=0; i<N; ++i) a[i] = b[i] + c[i] + d[i] + e[i];
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.