Post on 17-Jul-2015
λMore functional C++14
KnowCamp, Wrocław 25.03.2015
Sławomir Zborowski
Sławomir Zborowski @
Outline
Multiparadigm C++OOP vs functionalFunctional programming in generalFunctional C++14Data structures
target audience
goal
OOP, functional, or what?
It depends…
OOP vs functional
OOPfixed set of operations on thingscontinuously adding new things (classes)
Functionalfixed set of thingscontinuously adding new operations
The OOP way
operation
eatsleep
thing
CatDog
RaccoonMouse
The functional way
operation
eatsleep
thing
CatDog
RaccoonMouse
What's else wrong with OOP?
state (e.g in global variables)unexpected side effectsvalue mutabilitythreading difficult by design
State
Side effects1 String EvaluateSalaryAndReturnName(Employee e)2 {3 if (e.Title() == "CEO" || e.Salary() > 100000)4 {5 cout << e.First() << " " << e.Last()6 << " is overpaid" << endl;7 }8 return e.First() + " " + e.Last();9 }
(source: GoTW #20)
Value mutability 1 auto_ptr<Thing> groundbreakingOperations() 2 { 3 auto_ptr<Thing> thing (new Thing); 4 thing->value = 0x42; 5 6 processThing(thing); 7 8 return thing; 9 }
Threading
Functional programming
may solve
these problems.
OOP problems in functional world
OOP functional
state (e.g in globalvariables)
stateless
unexpected side effects pure functions
value mutability no variables
threading difficult bydesign
easy by design
The functional way
concept C++
no variables / SSA
lazy processing
higher-order functions
pattern matching
partial function application
recursion
�
�
☑
�
☑
☑
Functional C++
C++ version
C function pointer
C++03 function object
C++11 lambda expression
C++14 relaxed and generic lambdas
C++1z ??
Functional C++
Function C++
map
std::transformiter::imapboost::adaptrors::transformed
filter
std::remove_copy_ifiter::filterboost::adaptors::filtered
reduce
std::accumulateiter::accumulateboost::accumulate
accumulate 1 auto sum = 0; 2 for (auto const& n: in) { 3 auto v = n * n; 4 if (not (v % 2)) { 5 sum += v; 6 } 7 }
STL 1 decltype(in) out; 2 transform( 3 begin(in), 4 end(in), 5 back_inserter(out), 6 pow2); 7 out.erase( 8 remove_if( 9 begin(out),10 end(out),11 bind2nd(modulus<int>(), 2)),12 end(out));13 auto sum = accumulate(begin(out), end(out), 0);
CppIterTools
accumulate 1 auto sum = 0; 2 for (auto const& n: in) { 3 auto v = n * n; 4 if (not (v % 2)) { 5 sum += v; 6 } 7 }
1 auto sum = make_vector(2 iter::accumulate(3 iter::filter(4 not1(bind2nd(modulus<int>(), 2)),5 iter::imap(pow2, in)))).back();
Boost.Range
accumulate 1 auto sum = 0; 2 for (auto const& n: in) { 3 auto v = n * n; 4 if (not (v % 2)) { 5 sum += v; 6 } 7 }
1 auto sum = boost::accumulate(2 in | boost::adaptors::transformed(pow2)3 | boost::adaptors::filtered(4 not1(bind2nd(modulus<int>(), 2))),5 0);
Syntactic sugar?
Python1 sum([x ** 2 for x in in_ if not (x ** 2) % 2])
Haskell1 sum [x*x | x <- in_, even x]
List comprehension in C++
NaiveBoost.RangeRange comprehension LINQ for C++
(1) (2)(1) (2)
CppIterTools
uses lazy evaluation where possibleinspired by Python's itertools module
rangeenumerateziptakewhilecyclereversed…
Data structures
Immutable by designListsTreesstd::ropeVectors?
Bartosz Milewski / Okasaki
Performance
Performance
Concurrent performance!
Resources
Functional ProgrammingBartosz Milewski BlogEric Niebler on RangesFunctional C++ Blog
Libraries:, FC++ FTL
λ[ a s k q | q < - q s ]