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

generic programming galore using d
SMART_READER_LITE
LIVE PREVIEW

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


slide-1
SLIDE 1

c

2011 Andrei Alexandrescu

1 / 33

Generic Programming Galore Using D

Andrei Alexandrescu, PhD

Research Scientist Facebook

slide-2
SLIDE 2

37% off

c

2011 Andrei Alexandrescu

2 / 33

slide-3
SLIDE 3

Generic Programming

c

2011 Andrei Alexandrescu

3 / 33

slide-4
SLIDE 4

What is Generic Programming?

c

2011 Andrei Alexandrescu

4 / 33

slide-5
SLIDE 5

What is Generic Programming?

c

2011 Andrei Alexandrescu

4 / 33

  • Find most general algorithm representation
  • Narrowest requirements
  • Widest guarantees
  • Big-O() encapsulation should be a crime
  • No need to regress to hand-written code
slide-6
SLIDE 6

What is Generic Programming?

c

2011 Andrei Alexandrescu

4 / 33

  • 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
slide-7
SLIDE 7

What is Generic Programming?

c

2011 Andrei Alexandrescu

4 / 33

  • 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
slide-8
SLIDE 8

What is Generic Programming?

c

2011 Andrei Alexandrescu

4 / 33

  • 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!
slide-9
SLIDE 9

What is Generic Programming?

c

2011 Andrei Alexandrescu

4 / 33

  • 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

slide-10
SLIDE 10

Generic Programming

c

2011 Andrei Alexandrescu

5 / 33

  • “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”

slide-11
SLIDE 11

Warmup: the “dream min”

c

2011 Andrei Alexandrescu

6 / 33

  • 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
slide-12
SLIDE 12

First prototype

c

2011 Andrei Alexandrescu

7 / 33

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
slide-13
SLIDE 13

Variadic arguments

c

2011 Andrei Alexandrescu

8 / 33

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
slide-14
SLIDE 14

Reject nonsensical calls

c

2011 Andrei Alexandrescu

9 / 33

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
  • ver a collection
  • More work needed
  • Only accept types with a valid intersection
  • Only accept types comparable with ”<”
slide-15
SLIDE 15

Common type

c

2011 Andrei Alexandrescu

10 / 33

  • 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));

slide-16
SLIDE 16

Using CommonType

c

2011 Andrei Alexandrescu

11 / 33

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]; }

slide-17
SLIDE 17

How about min over many elements?

c

2011 Andrei Alexandrescu

12 / 33

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
slide-18
SLIDE 18

How about argmin now?

c

2011 Andrei Alexandrescu

13 / 33

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; }

slide-19
SLIDE 19

argmin

c

2011 Andrei Alexandrescu

14 / 33

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
slide-20
SLIDE 20

The Generative Connection

c

2011 Andrei Alexandrescu

15 / 33

slide-21
SLIDE 21

Generative programming

c

2011 Andrei Alexandrescu

16 / 33

  • In brief: code that generates code
  • Generic programming often requires algorithm

specialization

  • Specification often present in a DSL
slide-22
SLIDE 22

Embedded DSLs

c

2011 Andrei Alexandrescu

17 / 33

Force into host language’s syntax?

slide-23
SLIDE 23

Embedded DSLs

c

2011 Andrei Alexandrescu

18 / 33

  • Formatted printing?
slide-24
SLIDE 24

Embedded DSLs

c

2011 Andrei Alexandrescu

18 / 33

  • Formatted printing?
  • Regular expressions?
slide-25
SLIDE 25

Embedded DSLs

c

2011 Andrei Alexandrescu

18 / 33

  • Formatted printing?
  • Regular expressions?
  • EBNF?
slide-26
SLIDE 26

Embedded DSLs

c

2011 Andrei Alexandrescu

18 / 33

  • Formatted printing?
  • Regular expressions?
  • EBNF?
  • PEG?
slide-27
SLIDE 27

Embedded DSLs

c

2011 Andrei Alexandrescu

18 / 33

  • Formatted printing?
  • Regular expressions?
  • EBNF?
  • PEG?
  • SQL?
slide-28
SLIDE 28

Embedded DSLs

c

2011 Andrei Alexandrescu

18 / 33

  • Formatted printing?
  • Regular expressions?
  • EBNF?
  • PEG?
  • SQL?
  • . . . Pasta for everyone!
slide-29
SLIDE 29

Embedded DSLs

c

2011 Andrei Alexandrescu

19 / 33

Here: use with native grammar Process during compilation Generate D code accordingly

slide-30
SLIDE 30

Compile-Time Evaluation

c

2011 Andrei Alexandrescu

20 / 33

  • 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

slide-31
SLIDE 31

Code injection with mixin

c

2011 Andrei Alexandrescu

21 / 33

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. . .
slide-32
SLIDE 32

c

2011 Andrei Alexandrescu

22 / 33

Wait a minute!

slide-33
SLIDE 33

Example: bitfields in library

c

2011 Andrei Alexandrescu

23 / 33

struct A { int a; mixin(bitfields!( uint, "x", 2, int, "y", 3, uint, "z", 2, bool, "flag", 1)); } A obj;

  • bj.x = 2;
  • bj.z = obj.x;
slide-34
SLIDE 34

Parser

c

2011 Andrei Alexandrescu

24 / 33

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 "));

slide-35
SLIDE 35

Usage

c

2011 Andrei Alexandrescu

25 / 33

// 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);

slide-36
SLIDE 36

Scaling up

c

2011 Andrei Alexandrescu

26 / 33

1000 lines of D grammar → 3000 lines D parser

slide-37
SLIDE 37

c

2011 Andrei Alexandrescu

27 / 33

Highly integrated lex+yacc

slide-38
SLIDE 38

c

2011 Andrei Alexandrescu

28 / 33

What about regexen?

slide-39
SLIDE 39

Compile-time regular expressions

c

2011 Andrei Alexandrescu

29 / 33

  • 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

slide-40
SLIDE 40
slide-41
SLIDE 41

Summary

c

2011 Andrei Alexandrescu

31 / 33

slide-42
SLIDE 42

Summary

c

2011 Andrei Alexandrescu

32 / 33

  • Generic/generative programming—long unattained

promise

  • D’s angle
  • Powerful base language
  • Type manipulation
  • Compile-time evaluation
  • Code generation
slide-43
SLIDE 43

Grill the Speaker!

c

2011 Andrei Alexandrescu

33 / 33

More about ranges? • Thought the talk was boring • Intriguing! • He lost me at mixin • Awesome • Went over my head • Meh • I wonder how I can implement binary search • What’s for dinner? • Accent is bothersome • Real programmers use C • Must. . . control. . . fist. . .

  • f. . . death. . .