More functional C++14

Post on 17-Jul-2015

543 views 3 download

Transcript of More functional C++14

λ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]

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!

λ[ a s k q | q < - q s ]