Functional Programming in C++

  • 2,564 views
Uploaded on

Functional programming (FP) techniques produce code that is general, concise, composable, and correct. Until recently many of these techniques were limited to the realm of academia and esoteric …

Functional programming (FP) techniques produce code that is general, concise, composable, and correct. Until recently many of these techniques were limited to the realm of academia and esoteric programming languages. New C++ and boost developments enable us to embed FP in C++ in a seamless way.

We'll be covering recursive algebraic data types, curried functions, purity, generic programming, and category theory.

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
2,564
On Slideshare
0
From Embeds
0
Number of Embeds
1

Actions

Shares
Downloads
34
Comments
0
Likes
1

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Functional Programming Algebraic Data Types Functional Programming (in C++) What? Why? How (in C++)? unit, primitive type, one value, denoted () - Algebraic Data Types : (), :=, : =, , ⊕⊗ - Functions : a (b c) →→ con 20 - Generic Programming ost : (c◄C) → c int → bo David Sankel 10 - Category Theory : monoid, monad, etc. Sankel Software 1 2 3 Algebraic Data Types unit, primitive type, one value, denoted () + product, binary type operation, denoted a b, “a and b”, one of each ⊗ 4
  • 2. Algebraic Data Types Examples: Examples: unit, (), one value true : = () Z : = () product, a b, “a and b” ⊗ false : = () N := Z ⊕ N sum, a b, “a or b” ⊕ bool := true ⊕ false is the same as, a := b Z is implemented with unit. is implemented with, a : = b true is implemented with unit. A N value is the same as a Z value or an N false is implemented with unit. value. A bool value is the same as a true value or a false value. 7 8 9 Examples: Type Functions Type Functions Z : = () Add parameter on left side of : = or := [] : = () N := Z ⊕ N symbol that can be used on the right. L a := [] ⊗ ⊕ (a L a) [] : = () Say ai is a value of type a. and e is the z Z ∈ L a := [] ⊗ ⊕(a L a) N0 = (0,z) value of type []. A value of “L of a” is either a N1 = (1,N0) = (1,(0,z)) (0,e) (1,(ai,(0,e)) N2 = (1,N1) = (1,(1,(0,z))) value of [] or (a value of a and a value of 10 “L of a”). 11 (1,(aj,(1,(ai,(0,e)) 12
  • 3. Type Functions Algebraic Data Types Algebraic Data Types (in C++!) T a : = (T a ⊗ T a) ⊕ a - Abstract Our critera for functional concepts in C++ - No (minimal) syntax sugar, it scares Binary tree with values of type 'a' at the - Simple ((), :=, : =, , ⊕⊗ ) away the new bees. leaves. - Powerful - Mixes well with typical C++. - ... - No copycatting other languages and their limitations.. 13 14 15 Algebraic Data Types (in C++!) Algebraic Data Types (in C++!) Algebraic Data Types (in C++!) Easy ones Product Types Sum Types - Can use enum when underlying types - Unit (): use boost::mpl: void_ - z := a ⊗ ⊗ b c. struct. Named - are units, and accessors - aren't used elsewhere. - New unit types: T : = () struct T {}; -a ⊗ b. boost.fusion.vector. Access by - Can use a product type with an index. index - common and error prone - “is the same as”: a := b - Can use polymorphic base class. typedef b a; - boost.fusion.map. Both accessor methods. - not really nice syntax/error prone 16 17 18
  • 4. Algebraic Data Types (in C++!) Algebraic Data Types (in C++!) Algebraic Data Types (in C++!) “is implemented with , : =, wrap it in a struct ” Type Functions (:= style) Use “type function trait” from boost.mpl. Sum Types R01 : = double - boost.variant (best option!) struct R01 - arbitrary underlying types { explicit R01( const double impl_ ) none : = (), Op a := none⊕ a - small syntax overhead : impl( impl_ ) {} struct none{}; - access by index or type double impl; template< typename a > }; struct Op { - accessor functions (invariant typedef boost::variant<none,a> a b c ⊕ ⊕ guaranteed) boost::variant<a,b,c> - internal impl access function (invariant type; 19 requirement) 20 }; 21 Algebraic Data Types (in C++!) Algebraic Data Types (in C++!) What the heck is a recursive Type Functions (::= style) product type? Use a wrapper template struct Recursive Types S a := a ⊗ (S a) none : = (), Op a : = none ⊕ a - sum types: use make_recursive_variant struct none{}; - Seems like nonsense!? template< typename a > - product types: use struct Op { make_recursive_variant (see explicit Op( boost::variant<none,a>); paper for details) //... boost::variant<none,a> impl; }; 22 23 24
  • 5. What the heck is a recursive Laziness (in C++!) Laziness (in C++!) product type? How can we represent a computation of a How can we represent a computation of a S a := a ⊗ (S a) value in C++? value in C++? - Seems like nonsense!? - A 0 argument function. - Nope - Think of the recursion as being a computation of type (S a) - ... 25 26 27 Laziness (in C++!) What the heck is a recursive Functions product type? How can we represent a computation of a f:A → B value in C++? S a := a ⊗ (S a) - A 0 argument function. A set S of pairs (a,b) where a A b B. For ∈ ∈ - Streams of type a. See paper for a template< typename a> direct implementation. every a A, there exists exactly one ∈ struct lazy { typedef boost::function< a () > corresponding pair in S. type; }; 28 29 30
  • 6. What is a C++ function? What is a C++ function? What is a C++ function? bool f(int); bool f(int); => int bool → bool f(int); => int bool → What about multiple arguments? 31 32 33 What is a C++ function? Lets try another case. bool f2(int, int); 34
  • 7. What is a C++ function? What is a C++ function? Currying bool f3(int, int); (int int World) ⊗ ⊗ → Translation a⊗b→c { ++someglobalvar; (World bool) ⊗ to a → (b → c) R f(A1, A2,...,An); return true; } ^^^ (A1 ⊗ A2...An World) (World R) ⊗ → ⊗ - function returns a function (convenient) - (int int) bool doesn't work! → ⊗ - → is right associative - Consider the corresponding set. - Works with any function where - Introduce new parameter the domain is a product. and return value, World... 37 38 39 What is a C++ function? Translation R f(A1, A2,...,An); (A1⊗A2...An⊗World)→(World⊗R) ^^^ A1→A2...An→World→(World⊗R) ^^^ 40
  • 8. Functions (in C++) gfp library (netsuperbrain.com/gfp) - gfp::ciof (curried io function) - Converts a c++ function pointer into a function as we formulated. - gfp::cfunc (curried function) - cfunc<a,b,c>::type => function<function<c (b)> a> 43 Generic Programming Formulation: - Emptiable, a type class - A typeclass is a set of pairs (a,p) - a is a : = type or type function - p is a profile that fits certain patterns and laws - Our restrictions - At most one pair per type - Profile is a simple value 46
  • 9. Generic Programming (in C++!) Polymorphic Values: - Same type inference trick doesn't work for values. - Introduce resolve: resolve<std::vector<int>>( emptyThing ); - Polymorphic values must follow a Certain trait . . . 51 Generic Programming (in C++!) Generic Programming (in C++!) Generic Programming (in C++!) Polymorphic Values: Polymorphic Values & Functions: Polymorphic Classes: struct EmptyThing - Covers all generics we care about - Extendable collections of polymorphic { template<typename T> - Cannot be extended to support new values and functions. struct result; types without modification of underlying - Use partial template instantiation to //... code. select supported type. result<this_type(vector<int>*)>::type - No relation between related - The polymorphic entities select operator()( vector<int>* dummy ); polymorphic values and functions. appropriate instantiation when //... used. } emptyThing; 52 53 54
  • 10. Category Theory Category Theory Category Theory (Monoids) - deals abstractly with mathematical Monoids There are lots of monoids! structures and relations between them. A 0∈A - int, +, 0 : sum monoid + :A → A → A - bool, &&, true: all monoid - Gives some guidance as to what to do - string, concat, “”: string monoid with generics. - a → m: function monoid A, 0, and + form a monoid when + is - m monoid - Very powerful and expressive. associative and 0 is an identity for - forwards monoid operations to results. +. - io m: io monoid. Similar to function monoid. 55 56 57 Category Theory (Monoids) Category Theory Functional Programming (in C++!) Quick example: Much much more: FP Benefits: - header : Message → string - Cleaner design → Cleaner code - contents : Message → string - functor/pointed: functions, containers... - less code/static types → Less bugs - Powerful tools gfp::cfunc<Message,string> - idiom (applicative functors): FRP, streams FP (in C++) Benefits: payload = gfp::mplus( header )( contents ); - No need to switch languages - monad: arbitrary computations - Integrates well - called point free (pointless) programming!. - Easy to use (no special syntax) - foldable: compress collections - Highly Capable 58 59 60