Upgrade to Pro — share decks privately, control downloads, hide ads and more …

You Got Your Idris in My C++

You Got Your Idris in My C++

Programmers gripe that we have two kinds of programming languages: the ones we write in for fun, and the ones we write in because we have to. We may enjoy coding that weekend project in Agda, but we have to leave that smile behind on Monday morning when we go back to Java or C++.

But is that really the case? Or can we find a way of bringing the expressiveness, the rigor, or the fun of our favorite languages into our day jobs?

Erin Dees

June 25, 2015
Tweet

More Decks by Erin Dees

Other Decks in Programming

Transcript

  1. You got your Idris in my C++! A first look

    at
 denotational design Ian Dees • @undees Open Source Bridge 2015
  2. –Conal Elliott,
 “Denotational design with type class morphisms” “When designing

    software, in addition to innovating in your implementations, relate them to precise and familiar semantic models.”
  3. –Conal Elliott,
 “Denotational design with type class morphisms” “When designing

    software, in addition to innovating in your implementations, relate them to precise and familiar semantic models.”
  4. In other words… 1. Sketch your design in clear notation

    2. Implement it in your “day job” language
  5. In other words… 1. Sketch your design in (some kind

    of) clear notation 2. Implement it in your “day job” language
  6. -- A cousin of Haskell twice : Int -> Int

    twice x = 2 * x twice 42 —-> 84 : Int
  7. -- Types can be inputs to functions isNumeric : Type

    -> Bool isNumeric Int = True isNumeric String = False
  8. -- Types can be inputs to functions isNumeric : Type

    -> Bool isNumeric Int = True isNumeric String = False isNumeric Int --> True : Bool
  9. -- Idris, before we add dependent types data Vec :

    Type -> Type where Nil : Vec a (::) : a -> Vec a -> Vec a
 

  10. -- Idris, before we add dependent types data Vec :

    Type -> Type where Nil : Vec a (::) : a -> Vec a -> Vec a
 
 False :: True :: (the (Vec Bool) Nil) --> [False,True] : Vec Bool
  11. -- Idris data Vec : Nat -> Type -> Type

    where Nil : Vec Z a (::) : a -> Vec k a -> Vec (S k) a
  12. // C++ template <size_t k, typename T> class vec {

    public: static vec<0, T> nil; vec<k + 1, T> insert(T); };
  13. -- Peano numbers Z --> 0 S Z --> 1

    ("successor to zero") S (S Z) --> 2 ("successor to successor
 to zero")
  14. 42

  15. S (S (S (S (S (S (S (S (S (S

    (S (S (S (S (S (S (S (S (S (S (S (S (S (S (S (S (S (S (S (S (S (S (S (S (S (S (S (S (S (S (S (S Z))))))))))))))))
 ))))))))))))))))))))))) ))
  16. add : Vec n a -> Vec m a ->

    Vec (n + m) a add Nil ys = ys add (x :: xs) ys = x :: (add xs ys)
  17. add : Nat -> Nat -> Nat add Z y

    = y add (S x) y = S (add x y)
  18. 3 + 2 --> 5 : Integer 2 + 3

    --> 5 : Integer
  19. –Philip Wadler,
 “Propositions as Types” “For each proof of a

    given proposition, there is a program of the corresponding type—and vice versa.”
  20. -- Given natural numbers x and y, -- x +

    y equals y + x addCommutes : (x : Nat) -> (y : Nat) -> plus x y = plus y x
  21. Proof by induction Base case
 “It’s true for zero” Inductive

    step
 “If it’s true for x, then it’s true for x + 1”
  22. addCommutes Z y = ?base addCommutes (S x) y =

    let hypothesis = addCommutes x y in ?inductive
  23. > intros ---------- Other goals: ---------- { hole 0 }

    ---------- Assumptions: ---------- y : Nat ---------- Goal: ---------- { hole 1 }: y = plus y Z
  24. > intros ---------- Other goals: ---------- { hole 0 }

    ---------- Assumptions: ---------- y : Nat ---------- Goal: ---------- { hole 1 }: y = plus y Z
  25. > rewrite (plusZeroRightNeutral y) ---------- Other goals: ---------- { hole

    1 } { hole 0 } ---------- Assumptions: ---------- y : Nat ---------- Goal: ---------- { hole 2 }: plus y Z = plus y Z
  26. > rewrite (plusZeroRightNeutral y) ---------- Other goals: ---------- { hole

    1 } { hole 0 } ---------- Assumptions: ---------- y : Nat ---------- Goal: ---------- { hole 2 }: plus y Z = plus y Z
  27. > trivial base: No more goals. > qed Proof completed!

    Math.base = proof intros rewrite (plusZeroRightNeutral y) trivial
  28. > :p inductive ---------- Goal: ---------- { hole 0 }:

    (x : Nat) -> (y : Nat) -> (plus x y = plus y x) -> S (plus x y) = plus y (S x)
  29. > :p inductive ---------- Goal: ---------- { hole 0 }:

    (x : Nat) -> (y : Nat) -> (plus x y = plus y x) -> S (plus x y) = plus y (S x)
  30. > intros ---------- Other goals: ---------- { hole 2 }

    { hole 1 } { hole 0 } ---------- Assumptions: ---------- x : Nat y : Nat hypothesis : plus x y = plus y x ---------- Goal: ---------- { hole 3 }: S (plus x y) = plus y (S x)
  31. > intros ---------- Other goals: ---------- { hole 2 }

    { hole 1 } { hole 0 } ---------- Assumptions: ---------- x : Nat y : Nat hypothesis : plus x y = plus y x ---------- Goal: ---------- { hole 3 }: S (plus x y) = plus y (S x)
  32. > rewrite (plusSuccRightSucc y x) ---------- Other goals: ---------- {

    hole 3 } { hole 2 } { hole 1 } { hole 0 } ---------- Assumptions: ---------- x : Nat y : Nat hypothesis : plus x y = plus y x ---------- Goal: ---------- { hole 4 }: S (plus x y) = S (plus y x)
  33. > rewrite (plusSuccRightSucc y x) ---------- Other goals: ---------- {

    hole 3 } { hole 2 } { hole 1 } { hole 0 } ---------- Assumptions: ---------- x : Nat y : Nat hypothesis : plus x y = plus y x ---------- Goal: ---------- { hole 4 }: S (plus x y) = S (plus y x)
  34. > rewrite (plusSuccRightSucc y x) ---------- Other goals: ---------- {

    hole 3 } { hole 2 } { hole 1 } { hole 0 } ---------- Assumptions: ---------- x : Nat y : Nat hypothesis : plus x y = plus y x ---------- Goal: ---------- { hole 4 }: S (plus x y) = S (plus y x)
  35. > rewrite hypothesis ---------- Other goals: ---------- { hole 4

    } { hole 3 } { hole 2 } { hole 1 } { hole 0 } ---------- Assumptions: ---------- x : Nat y : Nat hypothesis : plus x y = plus y x ---------- Goal: ---------- { hole 5 }: S (plus x y) = S (plus x y)
  36. > rewrite hypothesis ---------- Other goals: ---------- { hole 4

    } { hole 3 } { hole 2 } { hole 1 } { hole 0 } ---------- Assumptions: ---------- x : Nat y : Nat hypothesis : plus x y = plus y x ---------- Goal: ---------- { hole 5 }: S (plus x y) = S (plus x y)
  37. > trivial inductive: No more goals. > qed Proof completed!

    Math.inductive = proof intros rewrite (plusSuccRightSucc y x) rewrite hypothesis trivial
  38. class Audio { public: size_t count() const; int16_t operator[](size_t i)

    const; int16_t& operator[](size_t i); double timeAtZero() const; double sampleRate() const; };
  39. class Audio { public: size_t count() const; int16_t operator[](size_t i)

    const; int16_t& operator[](size_t i); double timeAtZero() const; double sampleRate() const; double verticalScale() const; };
  40. class Audio { public: size_t count() const; int16_t operator[](size_t i)

    const; int16_t& operator[](size_t i); double timeAtZero() const; double sampleRate() const; double verticalScale() const; std::string fileName() const; std::string comments() const; bool isStereo() const; void loadFromFile(const std::string& filename); void saveToFile(const std::string& filename); };
  41. –Christopher McDougall,
 Born to Run “What else did we have

    going for us? Nothing, except we ran like crazy and stuck together.”