SlideShare une entreprise Scribd logo
1  sur  29
New Tools for a More
Functional C++
Sumant Tambe
Sr. Software Engineer, LinkedIn
Microsoft MVP
SF Bay Area ACCU
Sept 28, 2017
Blogger (since 2005)
Coditation—Elegant Code for Big Data
Author (wikibook) Open-source contributor
Since 2013 (Visual Studio and Dev Tech)
Functional Programming
in C++
by Ivan Cukic
(ETA early 2018)
Reviewer
Sum Types and (pseudo) Pattern Matching
Modeling Alternatives
Inheritance vs std::variant
• States of a game of Tennis
• NormalScore
• DeuceScore
• AdvantageScore
• GameCompleteScore
Modeling game states using std::variant
struct NormalScore {
Player p1, p2;
int p1_score, p2_score;
};
struct DeuceScore {
Player p1, p2;
};
struct AdvantageScore {
Player lead, lagging;
};
struct GameCompleteScore {
Player winner, loser;
int loser_score;
};
using GameState = std::variant<NormalScore, DeuceScore,
AdvantageScore, GameCompleteScore>;
Print GameState (std::variant)
struct GameStatePrinter {
std::ostream &o;
explicit GameStatePrinter(std::ostream& out) : o(out) {}
void operator ()(const NormalScore& ns) const {
o << "NormalScore[" << ns.p1 << ns.p2 << ns.p1_score << ns.p2_score << "]";
}
void operator ()(const DeuceScore& ds) const {
o << "DeuceScore[" << ds.p1 << "," << ds.p2 << "]";
}
void operator ()(const AdvantageScore& as) const {
o << "AdvantageScore[" << as.lead << "," << as.lagging << "]";
}
void operator ()(const GameCompleteScore& gc) const {
o << "GameComplete[" << gc.winner << gc.loser << gc.loser_score << "]";
}
};
std::ostream & operator << (std::ostream& o, const GameState& game) {
std::visit(GameStatePrinter(o), game);
return o;
}
std::visit spews blood when you miss a case
Print GameState. Fancier!
std::ostream & operator << (std::ostream& o, const GameState& game) {
std::visit(overloaded {
[&](const NormalScore& ns) {
o << "NormalScore" << ns.p1 << ns.p2 << ns.p1_score << ns.p2_score;
},
[&](const DeuceScore& gc) {
o << "DeuceScore[" << ds.p1 << "," << ds.p2 << "]";
},
[&](const AdvantageScore& as) {
o << "AdvantageScore[" << as.lead << "," << as.lagging << "]";
},
[&](const GameCompleteScore& gc) {
o << "GameComplete[" << gc.winner << gc.loser << gc.loser_score << "]";
}
}, game);
return o;
}
Passing Two Variants to std::visit
std::ostream & operator << (std::ostream& o, const GameState& game) {
std::visit(overloaded {
[&](const NormalScore& ns, const auto& other) {
o << "NormalScore" << ns.p1 << ns.p2 << ns.p1_score << ns.p2_score;
},
[&](const DeuceScore& gc, const auto& other) {
o << "DeuceScore[" << ds.p1 << "," << ds.p2 << "]";
},
[&](const AdvantageScore& as, const auto& other) {
o << "AdvantageScore[" << as.lead << "," << as.lagging << "]";
},
[&](const GameCompleteScore& gc, const auto& other) {
o << "GameComplete[" << gc.winner << gc.loser << gc.loser_score << "]";
}
}, game, someother_variant);
return o;
}
There can be arbitrary number of arbitrary variant types.
The visitor must cover all cases
A Template to Inherit Lambdas
template <class... Ts>
struct overloaded : Ts... {
using Ts::operator()...;
explicit overloaded(Ts... ts) : Ts(ts)... {}
};
A User-Defined Deduction Guide
explicit overloaded(Ts... ts) : Ts(ts)... {}
template <class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
Next GameState Algorithm (all cases in one place)
GameState next (const GameState& now,
const Player& who_scored)
{
return std::visit(overloaded {
[&](const DeuceScore& ds) -> GameState {
if (ds.p1 == who_scored)
return AdvantageScore{ds.p1, ds.p2};
else
return AdvantageScore{ds.p2, ds.p1};
},
[&](const AdvantageScore& as) -> GameState {
if (as.lead == who_scored)
return GameCompleteScore{as.lead, as.lagging, 40};
else
return DeuceScore{as.lead, as.lagging};
},
[&](const GameCompleteScore &) -> GameState {
throw "Illegal State";
},
[&](const NormalScore& ns) -> GameState {
if (ns.p1 == who_scored) {
switch (ns.p1_score) {
case 0: return NormalScore{ns.p1, ns.p2, 15, ns.p2_score};
case 15: return NormalScore{ns.p1, ns.p2, 30, ns.p2_score};
case 30: if (ns.p2_score < 40)
return NormalScore{ns.p1, ns.p2, 40, ns.p2_score};
else
return DeuceScore{ns.p1, ns.p2};
case 40: return GameCompleteScore{ns.p1, ns.p2, ns.p2_score};
default: throw "Makes no sense!";
}
}
else {
switch (ns.p2_score) {
case 0: return NormalScore{ns.p1, ns.p2, ns.p1_score, 15};
case 15: return NormalScore{ns.p1, ns.p2, ns.p1_score, 30};
case 30: if (ns.p1_score < 40)
return NormalScore{ns.p1, ns.p2, ns.p1_score, 40};
else
return DeuceScore{ns.p1, ns.p2};
case 40: return GameCompleteScore{ns.p2, ns.p1, ns.p1_score};
default: throw "Makes no sense!";
}
}
}
}, now);
}
Modeling Alternatives with Inheritance
class GameState {
std::unique_ptr<GameStateImpl> _state;
public:
void next(const Player& who_scored) {}
};
class GameStateImpl {
Player p1, p2;
public:
virtual GameStateImpl * next(
const Player& who_scored) = 0;
virtual ~GameStateImpl(){}
};
class NormalScore : public GameStateImpl {
int p1_score, p2_score;
public:
GameStateImpl * next(const Player&);
};
class DeuceScore : public GameStateImpl {
public:
GameStateImpl * next(const Player&);
};
class AdvantageScore : public GameStateImpl {
int lead;
public:
GameStateImpl * next(const Player&);
};
class GameCompleteScore :public GameStateImpl{
int winner, loser_score;
public:
GameStateImpl * next(const Player&);
};
Sharing State is easier with Inheritance
class GameState {
std::unique_ptr<GameStateImpl> _state;
public:
void next(const Player& who_scored) {}
Player& who_is_serving() const;
double fastest_serve_speed() const;
GameState get_last_state() const;
};
class GameStateImpl {
Player p1, p2;
int serving_player;
double speed;
GameState last_state;
public:
virtual GameStateImpl * next(
const Player& who_scored) = 0;
virtual Player& who_is_serving() const;
virtual double fastest_serve_speed() const;
virtual GameState get_last_state() const;
};
Sharing Common State is Repetitive with std::variant
Player who_is_serving = std::visit([](auto& s) {
return s.who_is_serving();
}, state);
Player who_is_serving = state.who_is_serving();
ceremony!
struct NormalScore {
Player p1, p2;
int p1_score, p2_score;
int serving_player;
Player & who_is_serving();
};
struct DeuceScore {
Player p1, p2;
int serving_player;
Player & who_is_serving();
};
struct AdvantageScore {
Player lead, lagging;
int serving_player;
Player & who_is_serving();
};
struct GameCompleteScore {
Player winner, loser;
int loser_score;
int serving_player;
Player & who_is_serving();
};
How about recursive std::variant?
struct NormalScore {
Player p1, p2;
int p1_score, p2_score;
int serving_player;
Player & who_is_serving();
GameState last_state;
};
struct DeuceScore {
Player p1, p2;
int serving_player;
Player & who_is_serving();
GameState last_state;
};
struct AdvantageScore {
Player lead, lagging;
int serving_player;
Player & who_is_serving();
GameState last_state;
};
struct GameCompleteScore {
Player winner, loser;
int loser_score;
int serving_player;
Player & who_is_serving();
GameState last_state;
};
Not possible unless you use recursive_wrapper and dynamic allocation.
Not in C++17.
Dare I say, it’s not algebraic? It does not compose 
std::variant is a container. Not an abstraction.
std::variant disables fluent interfaces
{
using GameState = std::variant<NormalScore, DeuceScore,
AdvantageScore, GameCompleteScore>;
GameState state = NormalScore {..};
GameState last_state = std::visit([](auto& s) {
return s.get_last_state();
}, state);
double last_speed = std::visit([](auto& s) {
return state.fastest_serve_speed();
}, last_state);
double last_speed = state.get_last_state().fastest_serve_speed();
}
ceremony!
Combine Implementation Inheritance with
std::variant
{
using GameState = std::variant<NormalScore_v2, DeuceScore_v2,
AdvantageScore_v2, GameCompleteScore_v2>;
GameState state = NormalScore_v2 {..};
Player who_is_serving = std::visit([](SharedGameState& s) {
return s.who_is_serving();
}, state);
Player who_is_serving = state.who_is_serving();
}
SharedGameState
who_is_serving()
NormalScore_v2 DeuceScore_v2 AdvantageScore_v2 GameCompleteScore_v2
ceremony!
Modeling Alternatives
Inheritance std::variant
Dynamic Allocation No dynamic allocation
Intrusive Non-intrusive
Reference semantics (how will you copy a
vector?)
Value semantics
Algorithm scattered into classes Algorithm in one place
Language supported
Clear errors if pure-virtual is not implemented
Library supported
std::visit spews blood on missing cases
Creates a first-class abstraction It’s just a container
Keeps fluent interfaces Disables fluent interfaces. Repeated std::visit
Supports recursive types (Composite) Must use recursive_wrapper and dynamic
allocation. Not in the C++17 standard.
Deep Immutability
const is shallow
struct X {
void bar();
};
struct Y {
X* xptr;
explicit Y(X* x) : xptr(x) {}
void foo() const {
xptr->bar();
}
};
{
const Y y(new X);
y.foo(); // mutates X??
}
Deep Immutability: propagate_const<T>
struct X {
void bar();
void bar() const; // Compiler error without this function
};
struct Y {
X* xptr;
propagate_const<X *> xptr;
explicit Y(X* x) : xptr(x) {}
void foo() const {
xptr->bar();
}
};
{
const Y y(new X);
y.foo(); // calls X.bar() const
}
Deep Immutability: propagate_const<T>
#include <experimental/propagate_const>
using std::experimental::propagate_const;
{
propagate_const<X *> xptr;
propagate_const<std::unique_ptr<X>> uptr;
propagate_const<std::shared_ptr<X>> shptr;
const propagate_const<std::shared_ptr<X>> c_shptr;
shptr.get() === X*
c_shptr.get() === const X*
*shptr === X&
*c_shptr === const X&
get_underlying(shptr) === shared_ptr<X>
get_underlying(c_shptr) === const shared_ptr<X>
shptr = another_shptr; // Error. Not copy-assignable
shptr = std::move(another_shptr) // but movable
Library fundamental TS v2
Mutable Temporaries
The Named Parameter Idiom (mutable)
class configs {
std::string server;
std::string protocol;
public:
configs & set_server(const std::string& s);
configs & set_protocol(const std::string& s);
};
start_server(configs().set_server(“localhost”)
.set_protocol(“https”));
The Named Parameter Idiom (immutable)
class configs {
public:
configs set_server(const std::string& s) const {
configs temp(*this); temp.server = s; return temp;
}
configs set_protocol(const std::string& proto) const {
configs temp(*this); temp.protocol = proto; return temp;
}
};
start_server(configs().set_server(“localhost”)
.set_protocol(“https”));
Avoid
copy-constructors?
The Named Parameter Idiom (immutable*)
class configs {
public:
configs set_server(const std::string& s) const {
configs temp(*this); temp.server = s; return temp;
}
configs set_protocol(const std::string& proto) const {
configs temp(*this); temp.protocol = proto; return temp;
}
configs set_server(const std::string& s) && {
server = s; return *this;
}
configs set_protocol(const std::string& proto) && {
protocol = proto; return *this;
}
};
start_server(configs().set_server(“localhost”)
.set_protocol(“https”));
&
&
The Named Parameter Idiom (immutable*)
class configs {
public:
configs set_server(const std::string& s) const {
configs temp(*this); temp.server = s; return temp;
}
configs set_protocol(const std::string& proto) const {
configs temp(*this); temp.protocol = proto; return temp;
}
configs&& set_server(const std::string& s) && {
server = s; return *this; std::move(*this);
}
configs&& set_protocol(const std::string& proto) && {
protocol = proto; return *this; std::move(*this);
}
};
start_server(configs().set_server(“localhost”)
.set_protocol(“https”));
&
&
Thank You!

Contenu connexe

Tendances

Probability Concept and Bayes Theorem
Probability Concept and Bayes TheoremProbability Concept and Bayes Theorem
Probability Concept and Bayes TheoremCherryBerry2
 
Metropolis-Hastings MCMC Short Tutorial
Metropolis-Hastings MCMC Short TutorialMetropolis-Hastings MCMC Short Tutorial
Metropolis-Hastings MCMC Short TutorialRalph Schlosser
 
Image Classification with Deep Learning | DevFest + GDay, George Town, Mala...
Image Classification with Deep Learning  |  DevFest + GDay, George Town, Mala...Image Classification with Deep Learning  |  DevFest + GDay, George Town, Mala...
Image Classification with Deep Learning | DevFest + GDay, George Town, Mala...Virot "Ta" Chiraphadhanakul
 
DISCRETE LOGARITHM PROBLEM
DISCRETE LOGARITHM PROBLEMDISCRETE LOGARITHM PROBLEM
DISCRETE LOGARITHM PROBLEMMANISH KUMAR
 
Generative Adversarial Networks (GAN)
Generative Adversarial Networks (GAN)Generative Adversarial Networks (GAN)
Generative Adversarial Networks (GAN)Manohar Mukku
 
All pairs shortest path algorithm
All pairs shortest path algorithmAll pairs shortest path algorithm
All pairs shortest path algorithmSrikrishnan Suresh
 
Lecture 1 maximum likelihood
Lecture 1 maximum likelihoodLecture 1 maximum likelihood
Lecture 1 maximum likelihoodAnant Dashpute
 
Implementation of k-means clustering algorithm in C
Implementation of k-means clustering algorithm in CImplementation of k-means clustering algorithm in C
Implementation of k-means clustering algorithm in CKasun Ranga Wijeweera
 
Probability&Bayes theorem
Probability&Bayes theoremProbability&Bayes theorem
Probability&Bayes theoremimran iqbal
 
Post quantum cryptography
Post quantum cryptographyPost quantum cryptography
Post quantum cryptographyMartins Okoi
 
The gale shapley algorithm
The gale shapley algorithmThe gale shapley algorithm
The gale shapley algorithmYung Chieh Tsai
 
Gdb basics for my sql db as (percona live europe 2019)
Gdb basics for my sql db as (percona live europe 2019)Gdb basics for my sql db as (percona live europe 2019)
Gdb basics for my sql db as (percona live europe 2019)Valerii Kravchuk
 
Mcq for Online Exam Soft Computing
Mcq for Online Exam Soft Computing Mcq for Online Exam Soft Computing
Mcq for Online Exam Soft Computing Shaheen Shaikh
 
Functional solid
Functional solidFunctional solid
Functional solidMatt Stine
 
Introduction to Probability and Bayes' Theorom
Introduction to Probability and Bayes' TheoromIntroduction to Probability and Bayes' Theorom
Introduction to Probability and Bayes' TheoromYugal Gupta
 
Lecture 5 6_7 - divide and conquer and method of solving recurrences
Lecture 5 6_7 - divide and conquer and method of solving recurrencesLecture 5 6_7 - divide and conquer and method of solving recurrences
Lecture 5 6_7 - divide and conquer and method of solving recurrencesjayavignesh86
 
tensor-decomposition
tensor-decompositiontensor-decomposition
tensor-decompositionKenta Oono
 
Information and network security 35 the chinese remainder theorem
Information and network security 35 the chinese remainder theoremInformation and network security 35 the chinese remainder theorem
Information and network security 35 the chinese remainder theoremVaibhav Khanna
 

Tendances (20)

Probability Concept and Bayes Theorem
Probability Concept and Bayes TheoremProbability Concept and Bayes Theorem
Probability Concept and Bayes Theorem
 
Self Organizing Maps
Self Organizing MapsSelf Organizing Maps
Self Organizing Maps
 
Metropolis-Hastings MCMC Short Tutorial
Metropolis-Hastings MCMC Short TutorialMetropolis-Hastings MCMC Short Tutorial
Metropolis-Hastings MCMC Short Tutorial
 
Image Classification with Deep Learning | DevFest + GDay, George Town, Mala...
Image Classification with Deep Learning  |  DevFest + GDay, George Town, Mala...Image Classification with Deep Learning  |  DevFest + GDay, George Town, Mala...
Image Classification with Deep Learning | DevFest + GDay, George Town, Mala...
 
DISCRETE LOGARITHM PROBLEM
DISCRETE LOGARITHM PROBLEMDISCRETE LOGARITHM PROBLEM
DISCRETE LOGARITHM PROBLEM
 
Generative Adversarial Networks (GAN)
Generative Adversarial Networks (GAN)Generative Adversarial Networks (GAN)
Generative Adversarial Networks (GAN)
 
Mle
MleMle
Mle
 
All pairs shortest path algorithm
All pairs shortest path algorithmAll pairs shortest path algorithm
All pairs shortest path algorithm
 
Lecture 1 maximum likelihood
Lecture 1 maximum likelihoodLecture 1 maximum likelihood
Lecture 1 maximum likelihood
 
Implementation of k-means clustering algorithm in C
Implementation of k-means clustering algorithm in CImplementation of k-means clustering algorithm in C
Implementation of k-means clustering algorithm in C
 
Probability&Bayes theorem
Probability&Bayes theoremProbability&Bayes theorem
Probability&Bayes theorem
 
Post quantum cryptography
Post quantum cryptographyPost quantum cryptography
Post quantum cryptography
 
The gale shapley algorithm
The gale shapley algorithmThe gale shapley algorithm
The gale shapley algorithm
 
Gdb basics for my sql db as (percona live europe 2019)
Gdb basics for my sql db as (percona live europe 2019)Gdb basics for my sql db as (percona live europe 2019)
Gdb basics for my sql db as (percona live europe 2019)
 
Mcq for Online Exam Soft Computing
Mcq for Online Exam Soft Computing Mcq for Online Exam Soft Computing
Mcq for Online Exam Soft Computing
 
Functional solid
Functional solidFunctional solid
Functional solid
 
Introduction to Probability and Bayes' Theorom
Introduction to Probability and Bayes' TheoromIntroduction to Probability and Bayes' Theorom
Introduction to Probability and Bayes' Theorom
 
Lecture 5 6_7 - divide and conquer and method of solving recurrences
Lecture 5 6_7 - divide and conquer and method of solving recurrencesLecture 5 6_7 - divide and conquer and method of solving recurrences
Lecture 5 6_7 - divide and conquer and method of solving recurrences
 
tensor-decomposition
tensor-decompositiontensor-decomposition
tensor-decomposition
 
Information and network security 35 the chinese remainder theorem
Information and network security 35 the chinese remainder theoremInformation and network security 35 the chinese remainder theorem
Information and network security 35 the chinese remainder theorem
 

Similaire à New Tools for a More Functional C++

Game programming-help
Game programming-helpGame programming-help
Game programming-helpSteve Nash
 
public interface Game Note interface in place of class { .pdf
public interface Game  Note interface in place of class { .pdfpublic interface Game  Note interface in place of class { .pdf
public interface Game Note interface in place of class { .pdfkavithaarp
 
David Kopal - Write better React with ReasonML - Codemotion Milan 2018
David Kopal - Write better React with ReasonML - Codemotion Milan 2018David Kopal - Write better React with ReasonML - Codemotion Milan 2018
David Kopal - Write better React with ReasonML - Codemotion Milan 2018Codemotion
 
C++You will design a program to play a simplified version of war, .pdf
C++You will design a program to play a simplified version of war, .pdfC++You will design a program to play a simplified version of war, .pdf
C++You will design a program to play a simplified version of war, .pdfezzi97
 
The Ring programming language version 1.5 book - Part 9 of 31
The Ring programming language version 1.5 book - Part 9 of 31The Ring programming language version 1.5 book - Part 9 of 31
The Ring programming language version 1.5 book - Part 9 of 31Mahmoud Samir Fayed
 
F# in the real world (NDC)
F# in the real world (NDC)F# in the real world (NDC)
F# in the real world (NDC)Yan Cui
 
The main class of the tictoe game looks like.public class Main {.pdf
The main class of the tictoe game looks like.public class Main {.pdfThe main class of the tictoe game looks like.public class Main {.pdf
The main class of the tictoe game looks like.public class Main {.pdfasif1401
 
Parallel Futures of a Game Engine
Parallel Futures of a Game EngineParallel Futures of a Game Engine
Parallel Futures of a Game EngineJohan Andersson
 
Modular games in Unity / Paweł Krakowiak (Rage Quit Games)
Modular games in Unity / Paweł Krakowiak (Rage Quit Games)Modular games in Unity / Paweł Krakowiak (Rage Quit Games)
Modular games in Unity / Paweł Krakowiak (Rage Quit Games)DevGAMM Conference
 
package com.tictactoe; public class Main {public void play() {.pdf
package com.tictactoe; public class Main {public void play() {.pdfpackage com.tictactoe; public class Main {public void play() {.pdf
package com.tictactoe; public class Main {public void play() {.pdfinfo430661
 
Games, AI, and Research - Part 2 Training (FightingICE AI Programming)
Games, AI, and Research - Part 2 Training (FightingICE AI Programming)Games, AI, and Research - Part 2 Training (FightingICE AI Programming)
Games, AI, and Research - Part 2 Training (FightingICE AI Programming)Pujana Paliyawan
 
WordPress Café November - Sport Leaderboards with a Plugin
WordPress Café November - Sport Leaderboards with a PluginWordPress Café November - Sport Leaderboards with a Plugin
WordPress Café November - Sport Leaderboards with a PluginExove
 
You will write a multi-interface version of the well-known concentra.pdf
You will write a multi-interface version of the well-known concentra.pdfYou will write a multi-interface version of the well-known concentra.pdf
You will write a multi-interface version of the well-known concentra.pdfFashionColZone
 
Ifgqueue.h#ifndef LFGQUEUE_H #define LFGQUEUE_H#include pl.pdf
Ifgqueue.h#ifndef LFGQUEUE_H #define LFGQUEUE_H#include pl.pdfIfgqueue.h#ifndef LFGQUEUE_H #define LFGQUEUE_H#include pl.pdf
Ifgqueue.h#ifndef LFGQUEUE_H #define LFGQUEUE_H#include pl.pdffazilfootsteps
 
Tips and Tricks for Avoiding Common Query Pitfalls Christian Kurze
Tips and Tricks for Avoiding Common Query Pitfalls Christian KurzeTips and Tricks for Avoiding Common Query Pitfalls Christian Kurze
Tips and Tricks for Avoiding Common Query Pitfalls Christian KurzeMongoDB
 
Tic tac toe on c++ project
Tic tac toe on c++ projectTic tac toe on c++ project
Tic tac toe on c++ projectUtkarsh Aggarwal
 
The Ring programming language version 1.8 book - Part 76 of 202
The Ring programming language version 1.8 book - Part 76 of 202The Ring programming language version 1.8 book - Part 76 of 202
The Ring programming language version 1.8 book - Part 76 of 202Mahmoud Samir Fayed
 
MongoDB World 2018: Tips and Tricks for Avoiding Common Query Pitfalls
MongoDB World 2018: Tips and Tricks for Avoiding Common Query PitfallsMongoDB World 2018: Tips and Tricks for Avoiding Common Query Pitfalls
MongoDB World 2018: Tips and Tricks for Avoiding Common Query PitfallsMongoDB
 
Bowling Game Kata in C# Adapted
Bowling Game Kata in C# AdaptedBowling Game Kata in C# Adapted
Bowling Game Kata in C# AdaptedMike Clement
 

Similaire à New Tools for a More Functional C++ (20)

Game programming-help
Game programming-helpGame programming-help
Game programming-help
 
public interface Game Note interface in place of class { .pdf
public interface Game  Note interface in place of class { .pdfpublic interface Game  Note interface in place of class { .pdf
public interface Game Note interface in place of class { .pdf
 
David Kopal - Write better React with ReasonML - Codemotion Milan 2018
David Kopal - Write better React with ReasonML - Codemotion Milan 2018David Kopal - Write better React with ReasonML - Codemotion Milan 2018
David Kopal - Write better React with ReasonML - Codemotion Milan 2018
 
C++You will design a program to play a simplified version of war, .pdf
C++You will design a program to play a simplified version of war, .pdfC++You will design a program to play a simplified version of war, .pdf
C++You will design a program to play a simplified version of war, .pdf
 
The Ring programming language version 1.5 book - Part 9 of 31
The Ring programming language version 1.5 book - Part 9 of 31The Ring programming language version 1.5 book - Part 9 of 31
The Ring programming language version 1.5 book - Part 9 of 31
 
F# in the real world (NDC)
F# in the real world (NDC)F# in the real world (NDC)
F# in the real world (NDC)
 
The main class of the tictoe game looks like.public class Main {.pdf
The main class of the tictoe game looks like.public class Main {.pdfThe main class of the tictoe game looks like.public class Main {.pdf
The main class of the tictoe game looks like.public class Main {.pdf
 
Parallel Futures of a Game Engine
Parallel Futures of a Game EngineParallel Futures of a Game Engine
Parallel Futures of a Game Engine
 
Modular games in Unity / Paweł Krakowiak (Rage Quit Games)
Modular games in Unity / Paweł Krakowiak (Rage Quit Games)Modular games in Unity / Paweł Krakowiak (Rage Quit Games)
Modular games in Unity / Paweł Krakowiak (Rage Quit Games)
 
package com.tictactoe; public class Main {public void play() {.pdf
package com.tictactoe; public class Main {public void play() {.pdfpackage com.tictactoe; public class Main {public void play() {.pdf
package com.tictactoe; public class Main {public void play() {.pdf
 
Games, AI, and Research - Part 2 Training (FightingICE AI Programming)
Games, AI, and Research - Part 2 Training (FightingICE AI Programming)Games, AI, and Research - Part 2 Training (FightingICE AI Programming)
Games, AI, and Research - Part 2 Training (FightingICE AI Programming)
 
WordPress Café November - Sport Leaderboards with a Plugin
WordPress Café November - Sport Leaderboards with a PluginWordPress Café November - Sport Leaderboards with a Plugin
WordPress Café November - Sport Leaderboards with a Plugin
 
You will write a multi-interface version of the well-known concentra.pdf
You will write a multi-interface version of the well-known concentra.pdfYou will write a multi-interface version of the well-known concentra.pdf
You will write a multi-interface version of the well-known concentra.pdf
 
Ifgqueue.h#ifndef LFGQUEUE_H #define LFGQUEUE_H#include pl.pdf
Ifgqueue.h#ifndef LFGQUEUE_H #define LFGQUEUE_H#include pl.pdfIfgqueue.h#ifndef LFGQUEUE_H #define LFGQUEUE_H#include pl.pdf
Ifgqueue.h#ifndef LFGQUEUE_H #define LFGQUEUE_H#include pl.pdf
 
Tic tac toe
Tic tac toeTic tac toe
Tic tac toe
 
Tips and Tricks for Avoiding Common Query Pitfalls Christian Kurze
Tips and Tricks for Avoiding Common Query Pitfalls Christian KurzeTips and Tricks for Avoiding Common Query Pitfalls Christian Kurze
Tips and Tricks for Avoiding Common Query Pitfalls Christian Kurze
 
Tic tac toe on c++ project
Tic tac toe on c++ projectTic tac toe on c++ project
Tic tac toe on c++ project
 
The Ring programming language version 1.8 book - Part 76 of 202
The Ring programming language version 1.8 book - Part 76 of 202The Ring programming language version 1.8 book - Part 76 of 202
The Ring programming language version 1.8 book - Part 76 of 202
 
MongoDB World 2018: Tips and Tricks for Avoiding Common Query Pitfalls
MongoDB World 2018: Tips and Tricks for Avoiding Common Query PitfallsMongoDB World 2018: Tips and Tricks for Avoiding Common Query Pitfalls
MongoDB World 2018: Tips and Tricks for Avoiding Common Query Pitfalls
 
Bowling Game Kata in C# Adapted
Bowling Game Kata in C# AdaptedBowling Game Kata in C# Adapted
Bowling Game Kata in C# Adapted
 

Plus de Sumant Tambe

Kafka tiered-storage-meetup-2022-final-presented
Kafka tiered-storage-meetup-2022-final-presentedKafka tiered-storage-meetup-2022-final-presented
Kafka tiered-storage-meetup-2022-final-presentedSumant Tambe
 
Systematic Generation Data and Types in C++
Systematic Generation Data and Types in C++Systematic Generation Data and Types in C++
Systematic Generation Data and Types in C++Sumant Tambe
 
Tuning kafka pipelines
Tuning kafka pipelinesTuning kafka pipelines
Tuning kafka pipelinesSumant Tambe
 
C++ Generators and Property-based Testing
C++ Generators and Property-based TestingC++ Generators and Property-based Testing
C++ Generators and Property-based TestingSumant Tambe
 
Reactive Stream Processing in Industrial IoT using DDS and Rx
Reactive Stream Processing in Industrial IoT using DDS and RxReactive Stream Processing in Industrial IoT using DDS and Rx
Reactive Stream Processing in Industrial IoT using DDS and RxSumant Tambe
 
RPC over DDS Beta 1
RPC over DDS Beta 1RPC over DDS Beta 1
RPC over DDS Beta 1Sumant Tambe
 
Remote Log Analytics Using DDS, ELK, and RxJS
Remote Log Analytics Using DDS, ELK, and RxJSRemote Log Analytics Using DDS, ELK, and RxJS
Remote Log Analytics Using DDS, ELK, and RxJSSumant Tambe
 
Property-based Testing and Generators (Lua)
Property-based Testing and Generators (Lua)Property-based Testing and Generators (Lua)
Property-based Testing and Generators (Lua)Sumant Tambe
 
Reactive Stream Processing for Data-centric Publish/Subscribe
Reactive Stream Processing for Data-centric Publish/SubscribeReactive Stream Processing for Data-centric Publish/Subscribe
Reactive Stream Processing for Data-centric Publish/SubscribeSumant Tambe
 
Reactive Stream Processing Using DDS and Rx
Reactive Stream Processing Using DDS and RxReactive Stream Processing Using DDS and Rx
Reactive Stream Processing Using DDS and RxSumant Tambe
 
Fun with Lambdas: C++14 Style (part 2)
Fun with Lambdas: C++14 Style (part 2)Fun with Lambdas: C++14 Style (part 2)
Fun with Lambdas: C++14 Style (part 2)Sumant Tambe
 
Fun with Lambdas: C++14 Style (part 1)
Fun with Lambdas: C++14 Style (part 1)Fun with Lambdas: C++14 Style (part 1)
Fun with Lambdas: C++14 Style (part 1)Sumant Tambe
 
An Extensible Architecture for Avionics Sensor Health Assessment Using DDS
An Extensible Architecture for Avionics Sensor Health Assessment Using DDSAn Extensible Architecture for Avionics Sensor Health Assessment Using DDS
An Extensible Architecture for Avionics Sensor Health Assessment Using DDSSumant Tambe
 
Overloading in Overdrive: A Generic Data-Centric Messaging Library for DDS
Overloading in Overdrive: A Generic Data-Centric Messaging Library for DDSOverloading in Overdrive: A Generic Data-Centric Messaging Library for DDS
Overloading in Overdrive: A Generic Data-Centric Messaging Library for DDSSumant Tambe
 
Standardizing the Data Distribution Service (DDS) API for Modern C++
Standardizing the Data Distribution Service (DDS) API for Modern C++Standardizing the Data Distribution Service (DDS) API for Modern C++
Standardizing the Data Distribution Service (DDS) API for Modern C++Sumant Tambe
 
Communication Patterns Using Data-Centric Publish/Subscribe
Communication Patterns Using Data-Centric Publish/SubscribeCommunication Patterns Using Data-Centric Publish/Subscribe
Communication Patterns Using Data-Centric Publish/SubscribeSumant Tambe
 
C++11 Idioms @ Silicon Valley Code Camp 2012
C++11 Idioms @ Silicon Valley Code Camp 2012 C++11 Idioms @ Silicon Valley Code Camp 2012
C++11 Idioms @ Silicon Valley Code Camp 2012 Sumant Tambe
 
Retargeting Embedded Software Stack for Many-Core Systems
Retargeting Embedded Software Stack for Many-Core SystemsRetargeting Embedded Software Stack for Many-Core Systems
Retargeting Embedded Software Stack for Many-Core SystemsSumant Tambe
 
Ph.D. Dissertation
Ph.D. DissertationPh.D. Dissertation
Ph.D. DissertationSumant Tambe
 

Plus de Sumant Tambe (20)

Kafka tiered-storage-meetup-2022-final-presented
Kafka tiered-storage-meetup-2022-final-presentedKafka tiered-storage-meetup-2022-final-presented
Kafka tiered-storage-meetup-2022-final-presented
 
Systematic Generation Data and Types in C++
Systematic Generation Data and Types in C++Systematic Generation Data and Types in C++
Systematic Generation Data and Types in C++
 
Tuning kafka pipelines
Tuning kafka pipelinesTuning kafka pipelines
Tuning kafka pipelines
 
C++ Coroutines
C++ CoroutinesC++ Coroutines
C++ Coroutines
 
C++ Generators and Property-based Testing
C++ Generators and Property-based TestingC++ Generators and Property-based Testing
C++ Generators and Property-based Testing
 
Reactive Stream Processing in Industrial IoT using DDS and Rx
Reactive Stream Processing in Industrial IoT using DDS and RxReactive Stream Processing in Industrial IoT using DDS and Rx
Reactive Stream Processing in Industrial IoT using DDS and Rx
 
RPC over DDS Beta 1
RPC over DDS Beta 1RPC over DDS Beta 1
RPC over DDS Beta 1
 
Remote Log Analytics Using DDS, ELK, and RxJS
Remote Log Analytics Using DDS, ELK, and RxJSRemote Log Analytics Using DDS, ELK, and RxJS
Remote Log Analytics Using DDS, ELK, and RxJS
 
Property-based Testing and Generators (Lua)
Property-based Testing and Generators (Lua)Property-based Testing and Generators (Lua)
Property-based Testing and Generators (Lua)
 
Reactive Stream Processing for Data-centric Publish/Subscribe
Reactive Stream Processing for Data-centric Publish/SubscribeReactive Stream Processing for Data-centric Publish/Subscribe
Reactive Stream Processing for Data-centric Publish/Subscribe
 
Reactive Stream Processing Using DDS and Rx
Reactive Stream Processing Using DDS and RxReactive Stream Processing Using DDS and Rx
Reactive Stream Processing Using DDS and Rx
 
Fun with Lambdas: C++14 Style (part 2)
Fun with Lambdas: C++14 Style (part 2)Fun with Lambdas: C++14 Style (part 2)
Fun with Lambdas: C++14 Style (part 2)
 
Fun with Lambdas: C++14 Style (part 1)
Fun with Lambdas: C++14 Style (part 1)Fun with Lambdas: C++14 Style (part 1)
Fun with Lambdas: C++14 Style (part 1)
 
An Extensible Architecture for Avionics Sensor Health Assessment Using DDS
An Extensible Architecture for Avionics Sensor Health Assessment Using DDSAn Extensible Architecture for Avionics Sensor Health Assessment Using DDS
An Extensible Architecture for Avionics Sensor Health Assessment Using DDS
 
Overloading in Overdrive: A Generic Data-Centric Messaging Library for DDS
Overloading in Overdrive: A Generic Data-Centric Messaging Library for DDSOverloading in Overdrive: A Generic Data-Centric Messaging Library for DDS
Overloading in Overdrive: A Generic Data-Centric Messaging Library for DDS
 
Standardizing the Data Distribution Service (DDS) API for Modern C++
Standardizing the Data Distribution Service (DDS) API for Modern C++Standardizing the Data Distribution Service (DDS) API for Modern C++
Standardizing the Data Distribution Service (DDS) API for Modern C++
 
Communication Patterns Using Data-Centric Publish/Subscribe
Communication Patterns Using Data-Centric Publish/SubscribeCommunication Patterns Using Data-Centric Publish/Subscribe
Communication Patterns Using Data-Centric Publish/Subscribe
 
C++11 Idioms @ Silicon Valley Code Camp 2012
C++11 Idioms @ Silicon Valley Code Camp 2012 C++11 Idioms @ Silicon Valley Code Camp 2012
C++11 Idioms @ Silicon Valley Code Camp 2012
 
Retargeting Embedded Software Stack for Many-Core Systems
Retargeting Embedded Software Stack for Many-Core SystemsRetargeting Embedded Software Stack for Many-Core Systems
Retargeting Embedded Software Stack for Many-Core Systems
 
Ph.D. Dissertation
Ph.D. DissertationPh.D. Dissertation
Ph.D. Dissertation
 

Dernier

Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfFerryKemperman
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Velvetech LLC
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作qr0udbr0
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...OnePlan Solutions
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureDinusha Kumarasiri
 
Precise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalPrecise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalLionel Briand
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Cizo Technology Services
 
How to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationHow to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationBradBedford3
 
Post Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on IdentityPost Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on Identityteam-WIBU
 
Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Rob Geurden
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesPhilip Schwarz
 
Salesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZSalesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZABSYZ Inc
 
Xen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfXen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfStefano Stabellini
 
Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringHironori Washizaki
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsAhmed Mohamed
 
Comparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfComparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfDrew Moseley
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024StefanoLambiase
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsChristian Birchler
 
VK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web DevelopmentVK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web Developmentvyaparkranti
 

Dernier (20)

Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdf
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...
 
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort ServiceHot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with Azure
 
Precise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalPrecise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive Goal
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
 
How to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationHow to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion Application
 
Post Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on IdentityPost Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on Identity
 
Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a series
 
Salesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZSalesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZ
 
Xen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfXen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdf
 
Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their Engineering
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML Diagrams
 
Comparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfComparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdf
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
 
VK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web DevelopmentVK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web Development
 

New Tools for a More Functional C++

  • 1. New Tools for a More Functional C++ Sumant Tambe Sr. Software Engineer, LinkedIn Microsoft MVP SF Bay Area ACCU Sept 28, 2017
  • 2. Blogger (since 2005) Coditation—Elegant Code for Big Data Author (wikibook) Open-source contributor Since 2013 (Visual Studio and Dev Tech)
  • 3. Functional Programming in C++ by Ivan Cukic (ETA early 2018) Reviewer
  • 4. Sum Types and (pseudo) Pattern Matching
  • 5. Modeling Alternatives Inheritance vs std::variant • States of a game of Tennis • NormalScore • DeuceScore • AdvantageScore • GameCompleteScore
  • 6. Modeling game states using std::variant struct NormalScore { Player p1, p2; int p1_score, p2_score; }; struct DeuceScore { Player p1, p2; }; struct AdvantageScore { Player lead, lagging; }; struct GameCompleteScore { Player winner, loser; int loser_score; }; using GameState = std::variant<NormalScore, DeuceScore, AdvantageScore, GameCompleteScore>;
  • 7. Print GameState (std::variant) struct GameStatePrinter { std::ostream &o; explicit GameStatePrinter(std::ostream& out) : o(out) {} void operator ()(const NormalScore& ns) const { o << "NormalScore[" << ns.p1 << ns.p2 << ns.p1_score << ns.p2_score << "]"; } void operator ()(const DeuceScore& ds) const { o << "DeuceScore[" << ds.p1 << "," << ds.p2 << "]"; } void operator ()(const AdvantageScore& as) const { o << "AdvantageScore[" << as.lead << "," << as.lagging << "]"; } void operator ()(const GameCompleteScore& gc) const { o << "GameComplete[" << gc.winner << gc.loser << gc.loser_score << "]"; } }; std::ostream & operator << (std::ostream& o, const GameState& game) { std::visit(GameStatePrinter(o), game); return o; }
  • 8. std::visit spews blood when you miss a case
  • 9. Print GameState. Fancier! std::ostream & operator << (std::ostream& o, const GameState& game) { std::visit(overloaded { [&](const NormalScore& ns) { o << "NormalScore" << ns.p1 << ns.p2 << ns.p1_score << ns.p2_score; }, [&](const DeuceScore& gc) { o << "DeuceScore[" << ds.p1 << "," << ds.p2 << "]"; }, [&](const AdvantageScore& as) { o << "AdvantageScore[" << as.lead << "," << as.lagging << "]"; }, [&](const GameCompleteScore& gc) { o << "GameComplete[" << gc.winner << gc.loser << gc.loser_score << "]"; } }, game); return o; }
  • 10. Passing Two Variants to std::visit std::ostream & operator << (std::ostream& o, const GameState& game) { std::visit(overloaded { [&](const NormalScore& ns, const auto& other) { o << "NormalScore" << ns.p1 << ns.p2 << ns.p1_score << ns.p2_score; }, [&](const DeuceScore& gc, const auto& other) { o << "DeuceScore[" << ds.p1 << "," << ds.p2 << "]"; }, [&](const AdvantageScore& as, const auto& other) { o << "AdvantageScore[" << as.lead << "," << as.lagging << "]"; }, [&](const GameCompleteScore& gc, const auto& other) { o << "GameComplete[" << gc.winner << gc.loser << gc.loser_score << "]"; } }, game, someother_variant); return o; } There can be arbitrary number of arbitrary variant types. The visitor must cover all cases
  • 11. A Template to Inherit Lambdas template <class... Ts> struct overloaded : Ts... { using Ts::operator()...; explicit overloaded(Ts... ts) : Ts(ts)... {} }; A User-Defined Deduction Guide explicit overloaded(Ts... ts) : Ts(ts)... {} template <class... Ts> overloaded(Ts...) -> overloaded<Ts...>;
  • 12. Next GameState Algorithm (all cases in one place) GameState next (const GameState& now, const Player& who_scored) { return std::visit(overloaded { [&](const DeuceScore& ds) -> GameState { if (ds.p1 == who_scored) return AdvantageScore{ds.p1, ds.p2}; else return AdvantageScore{ds.p2, ds.p1}; }, [&](const AdvantageScore& as) -> GameState { if (as.lead == who_scored) return GameCompleteScore{as.lead, as.lagging, 40}; else return DeuceScore{as.lead, as.lagging}; }, [&](const GameCompleteScore &) -> GameState { throw "Illegal State"; }, [&](const NormalScore& ns) -> GameState { if (ns.p1 == who_scored) { switch (ns.p1_score) { case 0: return NormalScore{ns.p1, ns.p2, 15, ns.p2_score}; case 15: return NormalScore{ns.p1, ns.p2, 30, ns.p2_score}; case 30: if (ns.p2_score < 40) return NormalScore{ns.p1, ns.p2, 40, ns.p2_score}; else return DeuceScore{ns.p1, ns.p2}; case 40: return GameCompleteScore{ns.p1, ns.p2, ns.p2_score}; default: throw "Makes no sense!"; } } else { switch (ns.p2_score) { case 0: return NormalScore{ns.p1, ns.p2, ns.p1_score, 15}; case 15: return NormalScore{ns.p1, ns.p2, ns.p1_score, 30}; case 30: if (ns.p1_score < 40) return NormalScore{ns.p1, ns.p2, ns.p1_score, 40}; else return DeuceScore{ns.p1, ns.p2}; case 40: return GameCompleteScore{ns.p2, ns.p1, ns.p1_score}; default: throw "Makes no sense!"; } } } }, now); }
  • 13. Modeling Alternatives with Inheritance class GameState { std::unique_ptr<GameStateImpl> _state; public: void next(const Player& who_scored) {} }; class GameStateImpl { Player p1, p2; public: virtual GameStateImpl * next( const Player& who_scored) = 0; virtual ~GameStateImpl(){} }; class NormalScore : public GameStateImpl { int p1_score, p2_score; public: GameStateImpl * next(const Player&); }; class DeuceScore : public GameStateImpl { public: GameStateImpl * next(const Player&); }; class AdvantageScore : public GameStateImpl { int lead; public: GameStateImpl * next(const Player&); }; class GameCompleteScore :public GameStateImpl{ int winner, loser_score; public: GameStateImpl * next(const Player&); };
  • 14. Sharing State is easier with Inheritance class GameState { std::unique_ptr<GameStateImpl> _state; public: void next(const Player& who_scored) {} Player& who_is_serving() const; double fastest_serve_speed() const; GameState get_last_state() const; }; class GameStateImpl { Player p1, p2; int serving_player; double speed; GameState last_state; public: virtual GameStateImpl * next( const Player& who_scored) = 0; virtual Player& who_is_serving() const; virtual double fastest_serve_speed() const; virtual GameState get_last_state() const; };
  • 15. Sharing Common State is Repetitive with std::variant Player who_is_serving = std::visit([](auto& s) { return s.who_is_serving(); }, state); Player who_is_serving = state.who_is_serving(); ceremony! struct NormalScore { Player p1, p2; int p1_score, p2_score; int serving_player; Player & who_is_serving(); }; struct DeuceScore { Player p1, p2; int serving_player; Player & who_is_serving(); }; struct AdvantageScore { Player lead, lagging; int serving_player; Player & who_is_serving(); }; struct GameCompleteScore { Player winner, loser; int loser_score; int serving_player; Player & who_is_serving(); };
  • 16. How about recursive std::variant? struct NormalScore { Player p1, p2; int p1_score, p2_score; int serving_player; Player & who_is_serving(); GameState last_state; }; struct DeuceScore { Player p1, p2; int serving_player; Player & who_is_serving(); GameState last_state; }; struct AdvantageScore { Player lead, lagging; int serving_player; Player & who_is_serving(); GameState last_state; }; struct GameCompleteScore { Player winner, loser; int loser_score; int serving_player; Player & who_is_serving(); GameState last_state; }; Not possible unless you use recursive_wrapper and dynamic allocation. Not in C++17. Dare I say, it’s not algebraic? It does not compose  std::variant is a container. Not an abstraction.
  • 17. std::variant disables fluent interfaces { using GameState = std::variant<NormalScore, DeuceScore, AdvantageScore, GameCompleteScore>; GameState state = NormalScore {..}; GameState last_state = std::visit([](auto& s) { return s.get_last_state(); }, state); double last_speed = std::visit([](auto& s) { return state.fastest_serve_speed(); }, last_state); double last_speed = state.get_last_state().fastest_serve_speed(); } ceremony!
  • 18. Combine Implementation Inheritance with std::variant { using GameState = std::variant<NormalScore_v2, DeuceScore_v2, AdvantageScore_v2, GameCompleteScore_v2>; GameState state = NormalScore_v2 {..}; Player who_is_serving = std::visit([](SharedGameState& s) { return s.who_is_serving(); }, state); Player who_is_serving = state.who_is_serving(); } SharedGameState who_is_serving() NormalScore_v2 DeuceScore_v2 AdvantageScore_v2 GameCompleteScore_v2 ceremony!
  • 19. Modeling Alternatives Inheritance std::variant Dynamic Allocation No dynamic allocation Intrusive Non-intrusive Reference semantics (how will you copy a vector?) Value semantics Algorithm scattered into classes Algorithm in one place Language supported Clear errors if pure-virtual is not implemented Library supported std::visit spews blood on missing cases Creates a first-class abstraction It’s just a container Keeps fluent interfaces Disables fluent interfaces. Repeated std::visit Supports recursive types (Composite) Must use recursive_wrapper and dynamic allocation. Not in the C++17 standard.
  • 21. const is shallow struct X { void bar(); }; struct Y { X* xptr; explicit Y(X* x) : xptr(x) {} void foo() const { xptr->bar(); } }; { const Y y(new X); y.foo(); // mutates X?? }
  • 22. Deep Immutability: propagate_const<T> struct X { void bar(); void bar() const; // Compiler error without this function }; struct Y { X* xptr; propagate_const<X *> xptr; explicit Y(X* x) : xptr(x) {} void foo() const { xptr->bar(); } }; { const Y y(new X); y.foo(); // calls X.bar() const }
  • 23. Deep Immutability: propagate_const<T> #include <experimental/propagate_const> using std::experimental::propagate_const; { propagate_const<X *> xptr; propagate_const<std::unique_ptr<X>> uptr; propagate_const<std::shared_ptr<X>> shptr; const propagate_const<std::shared_ptr<X>> c_shptr; shptr.get() === X* c_shptr.get() === const X* *shptr === X& *c_shptr === const X& get_underlying(shptr) === shared_ptr<X> get_underlying(c_shptr) === const shared_ptr<X> shptr = another_shptr; // Error. Not copy-assignable shptr = std::move(another_shptr) // but movable Library fundamental TS v2
  • 25. The Named Parameter Idiom (mutable) class configs { std::string server; std::string protocol; public: configs & set_server(const std::string& s); configs & set_protocol(const std::string& s); }; start_server(configs().set_server(“localhost”) .set_protocol(“https”));
  • 26. The Named Parameter Idiom (immutable) class configs { public: configs set_server(const std::string& s) const { configs temp(*this); temp.server = s; return temp; } configs set_protocol(const std::string& proto) const { configs temp(*this); temp.protocol = proto; return temp; } }; start_server(configs().set_server(“localhost”) .set_protocol(“https”)); Avoid copy-constructors?
  • 27. The Named Parameter Idiom (immutable*) class configs { public: configs set_server(const std::string& s) const { configs temp(*this); temp.server = s; return temp; } configs set_protocol(const std::string& proto) const { configs temp(*this); temp.protocol = proto; return temp; } configs set_server(const std::string& s) && { server = s; return *this; } configs set_protocol(const std::string& proto) && { protocol = proto; return *this; } }; start_server(configs().set_server(“localhost”) .set_protocol(“https”)); & &
  • 28. The Named Parameter Idiom (immutable*) class configs { public: configs set_server(const std::string& s) const { configs temp(*this); temp.server = s; return temp; } configs set_protocol(const std::string& proto) const { configs temp(*this); temp.protocol = proto; return temp; } configs&& set_server(const std::string& s) && { server = s; return *this; std::move(*this); } configs&& set_protocol(const std::string& proto) && { protocol = proto; return *this; std::move(*this); } }; start_server(configs().set_server(“localhost”) .set_protocol(“https”)); & &

Notes de l'éditeur

  1. How many of you think that it’s an important benefit that all cases are together.
  2. Who_is_serving visitor.
  3. Who_is_serving visitor.
  4. Who_is_serving visitor.
  5. *this is an lvalue. Still calls the copy-constructor.