generic programming galore using d
play

Generic Programming Galore Using D Andrei Alexandrescu, PhD - PowerPoint PPT Presentation

Generic Programming Galore Using D Andrei Alexandrescu, PhD Research Scientist Facebook 1 / 33 2011 Andrei Alexandrescu c 37% off 2 / 33 2011 Andrei Alexandrescu c Generic Programming 3 / 33 2011 Andrei Alexandrescu c What is


  1. Generic Programming Galore Using D Andrei Alexandrescu, PhD Research Scientist Facebook 1 / 33 � 2011 Andrei Alexandrescu c

  2. 37% off 2 / 33 � 2011 Andrei Alexandrescu c

  3. Generic Programming 3 / 33 � 2011 Andrei Alexandrescu c

  4. What is Generic Programming? 4 / 33 � 2011 Andrei Alexandrescu c

  5. What is Generic Programming? • Find most general algorithm representation ◦ Narrowest requirements ◦ Widest guarantees ◦ Big- O () encapsulation should be a crime ◦ No need to regress to hand-written code 4 / 33 � 2011 Andrei Alexandrescu c

  6. What is Generic Programming? • Find most general algorithm representation ◦ Narrowest requirements ◦ Widest guarantees ◦ Big- O () encapsulation should be a crime ◦ No need to regress to hand-written code • Define types to implement said requirements 4 / 33 � 2011 Andrei Alexandrescu c

  7. What is Generic Programming? • Find most general algorithm representation ◦ Narrowest requirements ◦ Widest guarantees ◦ Big- O () encapsulation should be a crime ◦ No need to regress to hand-written code • Define types to implement said requirements • Leverage the algorithm for ultimate reuse 4 / 33 � 2011 Andrei Alexandrescu c

  8. What is Generic Programming? • Find most general algorithm representation ◦ Narrowest requirements ◦ Widest guarantees ◦ Big- O () encapsulation should be a crime ◦ No need to regress to hand-written code • Define types to implement said requirements • Leverage the algorithm for ultimate reuse • . . . • Profit! 4 / 33 � 2011 Andrei Alexandrescu c

  9. What is Generic Programming? • Find most general algorithm representation ◦ Narrowest requirements ◦ Widest guarantees ◦ Big- O () encapsulation should be a crime ◦ No need to regress to hand-written code • Define types to implement said requirements • Leverage the algorithm for ultimate reuse • . . . • Profit! • Arguably one of the noblest endeavors of our m´ etier 4 / 33 � 2011 Andrei Alexandrescu c

  10. Generic Programming • “Write once, instantiate anywhere” ◦ Specialized implementations welcome • Prefers static type information and static expansion (macro style) • Fosters strong mathematical underpinnings ◦ Minimizing assumptions common theme in math • Tenuous relationship with binary interfaces • Starts with algorithms, not interfaces or objects • “Premature encapsulation is the root of some derangement” 5 / 33 � 2011 Andrei Alexandrescu c

  11. Warmup: the “dream min ” • Should work at efficiency comparable to hand-written code • Take variadic arguments : min(a, b, ...) ◦ Avoid nonsensical calls min() and min(a) • Work for all ordered types and conversions • Decline incompatible types, without prejudice 6 / 33 � 2011 Andrei Alexandrescu c

  12. First prototype auto min(L, R)(L lhs, R rhs) { return rhs < lhs ? rhs : lhs; } auto a = min(x, y); • This function is as efficient as any specialized, handwritten version (true genericity) • Deduction for argument types and result type 7 / 33 � 2011 Andrei Alexandrescu c

  13. Variadic arguments auto min(T...)(T x) { static if (x.length > 2) return min(min(x[0], x[1]), x[2 .. $]); else return x[0] > x[1] ? x[1] : x[0]; } ... auto m = min(a + b, 100, c); • x is not an array • This is not classic recursion 8 / 33 � 2011 Andrei Alexandrescu c

  14. Reject nonsensical calls auto min(T...)(T x) if (x.length > 1) { ... } • Rejects calls with 0 or 1 arguments • Allows other overloads to take over, e.g. min element over a collection • More work needed ◦ Only accept types with a valid intersection ◦ Only accept types comparable with ” < ” 9 / 33 � 2011 Andrei Alexandrescu c

  15. Common type • Task: Given a list of types, find the common type of all template CommonType(T...) { static if (T.length == 1) alias T[0] CommonType; else static if (is(typeof(1 ? T[0].init : T[1].init) U)) alias CommonType!(U, T[2 .. $]) CommonType; else alias void CommonType; } // Usage static assert(is(CommonType!(int, short, long) == long)); 10 / 33 � 2011 Andrei Alexandrescu c

  16. Using CommonType auto min(T...)(T x) if (x.length > 1 && is(typeof(CommonType!T.init < CommonType!T.init) == bool)) { static if (x.length > 2) return min(min(x[0], x[1]), x[2 .. $]); else return x[0] > x[1] ? x[1] : x[0]; } 11 / 33 � 2011 Andrei Alexandrescu c

  17. How about min over many elements? auto min(R)(R range) if (isInputRange!R && is(typeof(range.front < range.front) == bool)) { auto result = range.front; range.popFront(); foreach (e; range) { if (e < result) result = e; } return result; } auto m = [ 1, 5, 2, 0, 7, 9 ].min(); • Works over anything that can be iterated 12 / 33 � 2011 Andrei Alexandrescu c

  18. How about argmin now? auto argmin(alias fun, R)(R r) if (isInputRange!R && is(typeof(fun(r.front) < fun(r.front)) == bool)) { auto result = r.front; auto cache = fun(result); r.popFront(); foreach (e; r) { auto cand = fun(e); if (cand > cache) continue; result = e; cache = cand; } return result; } 13 / 33 � 2011 Andrei Alexandrescu c

  19. argmin auto s = ["abc", "a", "xz"]; auto m = s.argmin!((x) => x.length); • Works on anything iterable and any predicate • Predicate is passed by alias • No loss of efficiency 14 / 33 � 2011 Andrei Alexandrescu c

  20. The Generative Connection 15 / 33 � 2011 Andrei Alexandrescu c

  21. Generative programming • In brief: code that generates code • Generic programming often requires algorithm specialization • Specification often present in a DSL 16 / 33 � 2011 Andrei Alexandrescu c

  22. Embedded DSLs Force into host language’s syntax? 17 / 33 � 2011 Andrei Alexandrescu c

  23. Embedded DSLs • Formatted printing? 18 / 33 � 2011 Andrei Alexandrescu c

  24. Embedded DSLs • Formatted printing? • Regular expressions? 18 / 33 � 2011 Andrei Alexandrescu c

  25. Embedded DSLs • Formatted printing? • Regular expressions? • EBNF? 18 / 33 � 2011 Andrei Alexandrescu c

  26. Embedded DSLs • Formatted printing? • Regular expressions? • EBNF? • PEG? 18 / 33 � 2011 Andrei Alexandrescu c

  27. Embedded DSLs • Formatted printing? • Regular expressions? • EBNF? • PEG? • SQL? 18 / 33 � 2011 Andrei Alexandrescu c

  28. Embedded DSLs • Formatted printing? • Regular expressions? • EBNF? • PEG? • SQL? • . . . Pasta for everyone! 18 / 33 � 2011 Andrei Alexandrescu c

  29. Embedded DSLs Here: use with native grammar Process during compilation Generate D code accordingly 19 / 33 � 2011 Andrei Alexandrescu c

  30. Compile-Time Evaluation • A large subset of D available for compile-time evaluation ulong factorial(uint n) { ulong result = 1; foreach (i; 2 .. n) result *= i; return result; } ... auto f1 = factorial(10); // run-time static f2 = factorial(10); // compile-time 20 / 33 � 2011 Andrei Alexandrescu c

  31. Code injection with mixin mixin("writeln(\"hello, world\");"); mixin(generateSomeCode()); • Not as glamorous as AST manipulation but darn effective • Easy to understand and debug • Now we have compile-time evaluation AND mixin . . . 21 / 33 � 2011 Andrei Alexandrescu c

  32. Wait a minute! 22 / 33 � 2011 Andrei Alexandrescu c

  33. Example: bitfields in library struct A { int a; mixin(bitfields!( uint, "x", 2, int, "y", 3, uint, "z", 2, bool, "flag", 1)); } A obj; obj.x = 2; obj.z = obj.x; 23 / 33 � 2011 Andrei Alexandrescu c

  34. Parser import pegged.grammar; // by Philippe Sigaud mixin(grammar(" Expr < Factor AddExpr* AddExpr < (’+’/’-’) Factor Factor < Primary MulExpr* MulExpr < (’*’/’/’) Primary Primary < Parens / Number / Variable / ’-’ Primary Parens < ’(’ Expr ’)’ Number <~ [0-9]+ Variable <- Identifier ")); 24 / 33 � 2011 Andrei Alexandrescu c

  35. Usage // Parsing at compile-time: static parseTree1 = Expr.parse( "1 + 2 - (3*x-5)*6"); pragma(msg, parseTree1.capture); // Parsing at run-time: auto parseTree2 = Expr.parse(readln()); writeln(parseTree2.capture); 25 / 33 � 2011 Andrei Alexandrescu c

  36. Scaling up 1000 lines of D grammar → 3000 lines D parser 26 / 33 � 2011 Andrei Alexandrescu c

  37. Highly integrated lex+yacc 27 / 33 � 2011 Andrei Alexandrescu c

  38. What about regexen? 28 / 33 � 2011 Andrei Alexandrescu c

  39. Compile-time regular expressions • GSoC project by Dmitry Olshansky: FReD • Fully UTF capable, no special casing for ASCII • Two modes sharing the same backend: auto r1 = regex("^.*/([^/]+)/?$"); static r2 = ctRegex!("^.*/([^/]+)/?$"); • Run-time version uses intrinsics in a few places • Static version generates specialized automaton, then compiles it 29 / 33 � 2011 Andrei Alexandrescu c

  40. Summary 31 / 33 � 2011 Andrei Alexandrescu c

  41. Summary • Generic/generative programming—long unattained promise • D’s angle ◦ Powerful base language ◦ Type manipulation ◦ Compile-time evaluation ◦ Code generation 32 / 33 � 2011 Andrei Alexandrescu c

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend