SlideShare a Scribd company logo
Re-discovering 
Monads in C++ 
Bartosz Milewski, Бартош Милевски 
Twitter: @BartoszMilewski 
Novosibirsk, November 2014
Data in Boxes 
• Smart pointers: unique_ptr, shared_ptr 
• Optional, expected 
• Containers, ranges 
• Streams, channels (telemetry, stock quotes) 
• Futures 
• Database queries
In and Out of Boxes 
• Common patterns in data processing 
• Extract data from box 
• Process it 
• Put it back in a box 
for (int i = 0; i < len; ++i) 
w.push_back(f(v[i]));
Separate Concerns 
• Separate extraction/repacking from processing 
• Get rid of unessential variables 
• Iterators and algorithms: better but not much 
transform(begin(v), end(v), back_inserter(w), f);
Declarative Approach 
• Describe “what” rather than “how” 
• Example: ranges 
int total = accumulate(view::iota(1) | 
view::transform([](int x){return x*x;}) | 
view::take(10), 0);
Functor
Change of Perspective 
• Take a function that acts on items 
[](int x){return x*x;} 
• Lift it using view::transform 
view::transform([](int x){return x*x;}) 
• Lifted function acts on ranges of items {1, 2, 3, 4, …} 
view::iota(1) | 
view::transform([](int x){return x*x;}) 
• Returns a range of items {1, 4, 9, 16, …}
range 
1, 2, 3, 4 
range 
1, 4, 9, 16 
transform(square) 
transform 
x x*x 
square
Laziness 
• Infinite range {1, 2, 3, 4, …} 
std::iota(1) 
• Can’t process it eagerly! 
• Transform it lazily, on demand 
• Working with data that can’t fit in memory 
• infinite ranges 
• big data 
• database queries: LINQ
Functor Pattern 
• Function on types (type template) 
• Take any type T and produce Functor<T> 
• Function on functions 
• Take any function f from t1 to t2 
• Return a function from Functor<t1> to Functor<t2> 
• Preserve identity 
• Preserve composition
Range as Functor 
• Function on types: T to range<T> 
• Function on functions: view::transform 
view::iota(1) | 
view::transform([](int x){return x*x;}) | 
view::take(10)
future as Functor 
• A box that may eventually contain a value of type T 
std::future<T> fut = std::async(…); 
• Processing this value: 
auto x = fut.get(); // may block 
auto y = f(x); 
• Lifting a function using next: 
auto y = fut.next(f).get(); // proposed 
• fut.next(f).next(g).get();
Pointed Functor
Lifting Values 
• A pointed functor is a functor 
• Function on types 
• Function on functions (lifting functions) 
• Lifting a single value 
• A template function from T to Functor<T>
Examples 
• Containers: Creating a singleton container 
vector<double> {3.14} 
• Lazy range: view::single 
• Future: make_ready_future (proposed) 
• Usage: 
• return value when Functor expected 
• terminate recursion
Applicative Functor
Lifting Multi-Arg Functions 
• Applicative functor is a pointed functor: 
• Function on types 
• Lifting functions and values 
• Lifting multi-argument functions to functions taking 
multiple Functor arguments (of different types)
Lazy Applicative Range (1) 
• Example: Apply 2-arg function plus to two ranges 
zip_with(plus, r1, r2); 
• Variadic template zip_with 
• Takes a function f of n-arguments 
• Takes n ranges of corresponding types 
• Applies f to corresponding elements (until one of the 
ranges runs out) 
• Value lifting through repeat (infinite range)
Lazy Applicative Range (2) 
• Apply n-argument function to all combinations of 
values from n-ranges 
• Could be an overload of view::transform ? 
• Implemented as nested loop 
• Value lifting through single
Applicative Law 
• Lifting a 1-argument function 
• As function: transform(f, r) 
• As value (1): repeat(f) 
• Applying it to range: 
zip_with(apply, repeat(f), r) 
• As value (2): single(f) 
• Applying it to range: 
transform(apply, single(f), r)
Applicative future 
• Apply multi-argument function to multiple futures 
• Not planned, instead when_all 
• To apply the function, all arguments must be ready 
• Problem: futures may return exceptions, so it’s a 
combination of applicatives
Monad
Functor Factories 
• Library writer provides functions that return 
Functors 
• User wants to define their own 
• How do you chain Functor factories? 
Functor<t2> makeT2(t1); 
Functor<t3> makeT3(t2);
Future example 
• Composing asynchronous calls 
future<HANDLE> async_open(string &); 
future<Buffer> async_read(HANDLE fh); 
• Option 1: call get() twice 
• Option 2: call next. Problem: Double future. 
future<future<Buffer>> ffBuf = 
async_open(“foo").next(&async_read); 
• Solution: Collapse double future using unwrap() 
async_open("foo").next(&async_read).unwrap() 
.next(&async_process); 
• Better solution (proposed): Overload next for functions returning futures
Range Example 
• Functions returning ranges: Range factories 
• Applying range factory to range factory using 
transform results in a range of ranges 
• Collapsing using flatten 
• Combination of transform and flatten called 
for_each
Pythagorean Triples 
auto triples = 
for_each(ints(1), [](int z) { 
return for_each(ints(1, z), [=](int x) { 
return for_each(ints(x, z), [=](int y) { 
return yield_if(x*x + y*y == z*z, 
std::make_tuple(x, y, z)); 
}); 
}); 
}); 
• yield is the same as single inside for_each 
• yield_if is conditional yield (monad plus)
Monad 
• Monad is an applicative functor 
• function on types 
• function on functions: function lifting 
• value lifting 
• multi-argument function lifting 
• Flatten (reduce double Functor to single Functor) 
• Or Bind (combination of lifting and flatten) 
• And some monad laws
Current Problems 
• Lack of an overall abstraction (a monad template) 
• Random naming 
• fmap, transform, next, then, Select (LINQ) 
• pure, single, yield, await, make_ready_future 
• bind, for_each, next, then, SelectMany 
• Need syntactic sugar, like Haskell do notation 
• Resumable functions (proposed)
Conclusion 
• The same pattern fits many problems 
• ranges, lazy ranges 
• optional, expected 
• futures 
• LINQ (IEnumerable) 
• state, continuation, input, output 
• many more…

More Related Content

PDF
Rainer Grimm, “Functional Programming in C++11”
PDF
Александр Гранин, Функциональная 'Жизнь': параллельные клеточные автоматы и к...
PPTX
PVS-Studio team experience: checking various open source projects, or mistake...
PDF
Clojure intro
PDF
Yurii Shevtsov "V8 + libuv = Node.js. Under the hood"
PDF
Timur Shemsedinov "Пишу на колбеках, а что... (Асинхронное программирование)"
PDF
2 BytesC++ course_2014_c9_ pointers and dynamic arrays
PDF
Container adapters
Rainer Grimm, “Functional Programming in C++11”
Александр Гранин, Функциональная 'Жизнь': параллельные клеточные автоматы и к...
PVS-Studio team experience: checking various open source projects, or mistake...
Clojure intro
Yurii Shevtsov "V8 + libuv = Node.js. Under the hood"
Timur Shemsedinov "Пишу на колбеках, а что... (Асинхронное программирование)"
2 BytesC++ course_2014_c9_ pointers and dynamic arrays
Container adapters

What's hot (20)

PDF
Polymorphism
PDF
서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015
PDF
Introduction to functional programming using Ocaml
PDF
Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...
PDF
Beyond tf idf why, what & how
PDF
Swift for tensorflow
PDF
Java8 stream
PPTX
Chapter 7 functions (c)
PDF
C programs
PDF
Extend R with Rcpp!!!
PPT
Lecture 12: Classes and Files
PPTX
Advanced JavaScript
PDF
Frsa
PPTX
How to add an optimization for C# to RyuJIT
PDF
C++ references
PPT
20100712-OTcl Command -- Getting Started
PDF
Recursion to iteration automation.
PDF
20140531 serebryany lecture02_find_scary_cpp_bugs
PPT
Computer Programming- Lecture 9
Polymorphism
서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015
Introduction to functional programming using Ocaml
Java/Scala Lab: Анатолий Кметюк - Scala SubScript: Алгебра для реактивного пр...
Beyond tf idf why, what & how
Swift for tensorflow
Java8 stream
Chapter 7 functions (c)
C programs
Extend R with Rcpp!!!
Lecture 12: Classes and Files
Advanced JavaScript
Frsa
How to add an optimization for C# to RyuJIT
C++ references
20100712-OTcl Command -- Getting Started
Recursion to iteration automation.
20140531 serebryany lecture02_find_scary_cpp_bugs
Computer Programming- Lecture 9
Ad

Similar to Bartosz Milewski, “Re-discovering Monads in C++” (20)

PPTX
C++11: Feel the New Language
PPTX
Fuel Up JavaScript with Functional Programming
PDF
Booting into functional programming
PPTX
Intro to Functional Programming
PDF
Functional programming in C++
PDF
The present and the future of functional programming in c++
PDF
Christian Gill ''Functional programming for the people''
PDF
Web futures
PPTX
Good functional programming is good programming
PPTX
Functional programming for the Advanced Beginner
PDF
Generic programming and concepts that should be in C++
PPTX
Столпы функционального программирования для адептов ООП, Николай Мозговой
PDF
Functional programming techniques in regular JavaScript
PDF
The Present and The Future of Functional Programming in C++
PDF
3 FP Concepts: Recursion, List Comprehensions and Monads
PDF
Introduction to functional programming (In Arabic)
PDF
How to Lose Functional Programming at Work
PDF
Functional Programming in the Wild
PPTX
Advanced Functional Programming in Scala
KEY
Exciting JavaScript - Part I
C++11: Feel the New Language
Fuel Up JavaScript with Functional Programming
Booting into functional programming
Intro to Functional Programming
Functional programming in C++
The present and the future of functional programming in c++
Christian Gill ''Functional programming for the people''
Web futures
Good functional programming is good programming
Functional programming for the Advanced Beginner
Generic programming and concepts that should be in C++
Столпы функционального программирования для адептов ООП, Николай Мозговой
Functional programming techniques in regular JavaScript
The Present and The Future of Functional Programming in C++
3 FP Concepts: Recursion, List Comprehensions and Monads
Introduction to functional programming (In Arabic)
How to Lose Functional Programming at Work
Functional Programming in the Wild
Advanced Functional Programming in Scala
Exciting JavaScript - Part I
Ad

More from Platonov Sergey (20)

PPTX
Евгений Зуев, С++ в России: Стандарт языка и его реализация
PPTX
Алексей Кутумов, C++ без исключений, часть 3
PPTX
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
PPT
Евгений Крутько, Многопоточные вычисления, современный подход.
PDF
Тененёв Анатолий, Boost.Asio в алгоритмической торговле
PPTX
Павел Беликов, Опыт мигрирования крупного проекта с Windows-only на Linux
PDF
Дмитрий Кашицын, Вывод типов в динамических и не очень языках II
PDF
Дмитрий Кашицын, Вывод типов в динамических и не очень языках I
PDF
QML\Qt Quick на практике
PDF
Визуализация автомобильных маршрутов
PDF
Функциональный микроскоп: линзы в C++
PDF
C++ exceptions
PPTX
Как мы уменьшили количество ошибок в Unreal Engine с помощью статического ана...
PDF
HPX: C++11 runtime система для параллельных и распределённых вычислений
PPTX
Ranges calendar-novosibirsk-2015-08
PDF
Использование maven для сборки больших модульных c++ проектов на примере Odin...
PDF
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведения
PDF
One definition rule - что это такое, и как с этим жить
PDF
DI в C++ тонкости и нюансы
PPTX
Аскетичная разработка браузера
Евгений Зуев, С++ в России: Стандарт языка и его реализация
Алексей Кутумов, C++ без исключений, часть 3
Евгений Рыжков, Андрей Карпов Как потратить 10 лет на разработку анализатора ...
Евгений Крутько, Многопоточные вычисления, современный подход.
Тененёв Анатолий, Boost.Asio в алгоритмической торговле
Павел Беликов, Опыт мигрирования крупного проекта с Windows-only на Linux
Дмитрий Кашицын, Вывод типов в динамических и не очень языках II
Дмитрий Кашицын, Вывод типов в динамических и не очень языках I
QML\Qt Quick на практике
Визуализация автомобильных маршрутов
Функциональный микроскоп: линзы в C++
C++ exceptions
Как мы уменьшили количество ошибок в Unreal Engine с помощью статического ана...
HPX: C++11 runtime система для параллельных и распределённых вычислений
Ranges calendar-novosibirsk-2015-08
Использование maven для сборки больших модульных c++ проектов на примере Odin...
Дракон в мешке: от LLVM к C++ и проблемам неопределенного поведения
One definition rule - что это такое, и как с этим жить
DI в C++ тонкости и нюансы
Аскетичная разработка браузера

Recently uploaded (20)

PPTX
MYSQL Presentation for SQL database connectivity
PDF
Unlocking AI with Model Context Protocol (MCP)
PPTX
Tartificialntelligence_presentation.pptx
PDF
gpt5_lecture_notes_comprehensive_20250812015547.pdf
PPTX
Spectroscopy.pptx food analysis technology
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PDF
Video forgery: An extensive analysis of inter-and intra-frame manipulation al...
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PDF
Assigned Numbers - 2025 - Bluetooth® Document
PDF
Getting Started with Data Integration: FME Form 101
PDF
Empathic Computing: Creating Shared Understanding
PPTX
SOPHOS-XG Firewall Administrator PPT.pptx
PDF
NewMind AI Weekly Chronicles - August'25-Week II
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PPTX
Programs and apps: productivity, graphics, security and other tools
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
PPTX
A Presentation on Artificial Intelligence
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PDF
Accuracy of neural networks in brain wave diagnosis of schizophrenia
PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
MYSQL Presentation for SQL database connectivity
Unlocking AI with Model Context Protocol (MCP)
Tartificialntelligence_presentation.pptx
gpt5_lecture_notes_comprehensive_20250812015547.pdf
Spectroscopy.pptx food analysis technology
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
Video forgery: An extensive analysis of inter-and intra-frame manipulation al...
Digital-Transformation-Roadmap-for-Companies.pptx
Assigned Numbers - 2025 - Bluetooth® Document
Getting Started with Data Integration: FME Form 101
Empathic Computing: Creating Shared Understanding
SOPHOS-XG Firewall Administrator PPT.pptx
NewMind AI Weekly Chronicles - August'25-Week II
Mobile App Security Testing_ A Comprehensive Guide.pdf
Programs and apps: productivity, graphics, security and other tools
Building Integrated photovoltaic BIPV_UPV.pdf
A Presentation on Artificial Intelligence
Agricultural_Statistics_at_a_Glance_2022_0.pdf
Accuracy of neural networks in brain wave diagnosis of schizophrenia
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf

Bartosz Milewski, “Re-discovering Monads in C++”

  • 1. Re-discovering Monads in C++ Bartosz Milewski, Бартош Милевски Twitter: @BartoszMilewski Novosibirsk, November 2014
  • 2. Data in Boxes • Smart pointers: unique_ptr, shared_ptr • Optional, expected • Containers, ranges • Streams, channels (telemetry, stock quotes) • Futures • Database queries
  • 3. In and Out of Boxes • Common patterns in data processing • Extract data from box • Process it • Put it back in a box for (int i = 0; i < len; ++i) w.push_back(f(v[i]));
  • 4. Separate Concerns • Separate extraction/repacking from processing • Get rid of unessential variables • Iterators and algorithms: better but not much transform(begin(v), end(v), back_inserter(w), f);
  • 5. Declarative Approach • Describe “what” rather than “how” • Example: ranges int total = accumulate(view::iota(1) | view::transform([](int x){return x*x;}) | view::take(10), 0);
  • 7. Change of Perspective • Take a function that acts on items [](int x){return x*x;} • Lift it using view::transform view::transform([](int x){return x*x;}) • Lifted function acts on ranges of items {1, 2, 3, 4, …} view::iota(1) | view::transform([](int x){return x*x;}) • Returns a range of items {1, 4, 9, 16, …}
  • 8. range 1, 2, 3, 4 range 1, 4, 9, 16 transform(square) transform x x*x square
  • 9. Laziness • Infinite range {1, 2, 3, 4, …} std::iota(1) • Can’t process it eagerly! • Transform it lazily, on demand • Working with data that can’t fit in memory • infinite ranges • big data • database queries: LINQ
  • 10. Functor Pattern • Function on types (type template) • Take any type T and produce Functor<T> • Function on functions • Take any function f from t1 to t2 • Return a function from Functor<t1> to Functor<t2> • Preserve identity • Preserve composition
  • 11. Range as Functor • Function on types: T to range<T> • Function on functions: view::transform view::iota(1) | view::transform([](int x){return x*x;}) | view::take(10)
  • 12. future as Functor • A box that may eventually contain a value of type T std::future<T> fut = std::async(…); • Processing this value: auto x = fut.get(); // may block auto y = f(x); • Lifting a function using next: auto y = fut.next(f).get(); // proposed • fut.next(f).next(g).get();
  • 14. Lifting Values • A pointed functor is a functor • Function on types • Function on functions (lifting functions) • Lifting a single value • A template function from T to Functor<T>
  • 15. Examples • Containers: Creating a singleton container vector<double> {3.14} • Lazy range: view::single • Future: make_ready_future (proposed) • Usage: • return value when Functor expected • terminate recursion
  • 17. Lifting Multi-Arg Functions • Applicative functor is a pointed functor: • Function on types • Lifting functions and values • Lifting multi-argument functions to functions taking multiple Functor arguments (of different types)
  • 18. Lazy Applicative Range (1) • Example: Apply 2-arg function plus to two ranges zip_with(plus, r1, r2); • Variadic template zip_with • Takes a function f of n-arguments • Takes n ranges of corresponding types • Applies f to corresponding elements (until one of the ranges runs out) • Value lifting through repeat (infinite range)
  • 19. Lazy Applicative Range (2) • Apply n-argument function to all combinations of values from n-ranges • Could be an overload of view::transform ? • Implemented as nested loop • Value lifting through single
  • 20. Applicative Law • Lifting a 1-argument function • As function: transform(f, r) • As value (1): repeat(f) • Applying it to range: zip_with(apply, repeat(f), r) • As value (2): single(f) • Applying it to range: transform(apply, single(f), r)
  • 21. Applicative future • Apply multi-argument function to multiple futures • Not planned, instead when_all • To apply the function, all arguments must be ready • Problem: futures may return exceptions, so it’s a combination of applicatives
  • 22. Monad
  • 23. Functor Factories • Library writer provides functions that return Functors • User wants to define their own • How do you chain Functor factories? Functor<t2> makeT2(t1); Functor<t3> makeT3(t2);
  • 24. Future example • Composing asynchronous calls future<HANDLE> async_open(string &); future<Buffer> async_read(HANDLE fh); • Option 1: call get() twice • Option 2: call next. Problem: Double future. future<future<Buffer>> ffBuf = async_open(“foo").next(&async_read); • Solution: Collapse double future using unwrap() async_open("foo").next(&async_read).unwrap() .next(&async_process); • Better solution (proposed): Overload next for functions returning futures
  • 25. Range Example • Functions returning ranges: Range factories • Applying range factory to range factory using transform results in a range of ranges • Collapsing using flatten • Combination of transform and flatten called for_each
  • 26. Pythagorean Triples auto triples = for_each(ints(1), [](int z) { return for_each(ints(1, z), [=](int x) { return for_each(ints(x, z), [=](int y) { return yield_if(x*x + y*y == z*z, std::make_tuple(x, y, z)); }); }); }); • yield is the same as single inside for_each • yield_if is conditional yield (monad plus)
  • 27. Monad • Monad is an applicative functor • function on types • function on functions: function lifting • value lifting • multi-argument function lifting • Flatten (reduce double Functor to single Functor) • Or Bind (combination of lifting and flatten) • And some monad laws
  • 28. Current Problems • Lack of an overall abstraction (a monad template) • Random naming • fmap, transform, next, then, Select (LINQ) • pure, single, yield, await, make_ready_future • bind, for_each, next, then, SelectMany • Need syntactic sugar, like Haskell do notation • Resumable functions (proposed)
  • 29. Conclusion • The same pattern fits many problems • ranges, lazy ranges • optional, expected • futures • LINQ (IEnumerable) • state, continuation, input, output • many more…