KEMBAR78
Functional Programming in C++ | PDF
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
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
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
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
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
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
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
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
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
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

Functional Programming in C++

  • 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 heckis 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 aC++ 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 aC++ 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++) gfplibrary (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 (inC++!) 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