2. Plan
● Functional Programming in C++
● Concurrent models
● Software Transactional Memory
● Monadic STM in C++
● Advanced Functional Programming in C++
22. template <typename A>
STML<TVar<A>> newTVar(const A& val);
template <typename A>
STML<A> readTVar(const TVar<A>& tvar);
STM: TVar operations
newTVar :: a → STML (TVar a)
readTVar :: TVar a → STML a
23. template <typename A>
STML<TVar<A>> newTVar(const A& val);
template <typename A>
STML<A> readTVar(const TVar<A>& tvar);
template <typename A>
STML<Unit> writeTVar(const TVar<A>& tvar,
const A& val);
STM: TVar operations
newTVar :: a → STML (TVar a)
readTVar :: TVar a → STML a
writeTVar :: TVar a → a → STML ()
24. STM: Monadically composable transactions
transaction :: STML Int
transaction = do
tvar ← newTVar 10
readTVar tvar
STML<int> transaction() {
STML<TVar<int>> tvarTrans = newTVar(10);
// return readTVar(tvarTrans);
// ????
}
30. template <typename A, typename Ret>
struct NewTVar
{
A val;
std::function<Ret(TVar<A>)> next;
};
template <typename A, typename Ret>
struct ReadTVar
{
TVar<A> tvar;
std::function<Ret(A)> next;
};
template <typename A, typename Ret>
struct WriteTVar
{
TVar<A> tvar;
A val;
std::function<Ret(fp::Unit)> next;
};
template <typename A, typename Ret>
struct Retry
{
};
STM eDSL
31. template <class Ret>
struct STMF
{
std::variant<NewTVar <std::any, Ret>,
ReadTVar <std::any, Ret>,
WriteTVar <std::any, Ret>,
Retry <std::any, Ret>
> stmf;
};
STM eDSL Generalized ADT
data STMF next where
NewTVar :: a -> (TVar a -> next) -> STMF next
WriteTVar :: TVar a -> a -> next -> STMF next
ReadTVar :: TVar a -> (a -> next) -> STMF next
Retry :: STMF next
38. Free monads
-- Free monad, normal form
data Free f a = Pure a
| Bind (f (Free f a))
Binding complexity: O(n2
)
<stm/free/stm.h>
39. Free monads
-- Free monad, normal form
data Free f a = Pure a
| Bind (f (Free f a))
-- Free monad, Church-encoded form
data ChurchFree f a
= ChurchFree { runChurch :: forall z. (a -> z)
-> (f z -> z)
-> z }
Binding complexity: O(n2
)
<stm/free/stm.h>
Binding complexity: O(n)
<stm/church/stm.h>
(10x faster)
40. Free monads
-- Free monad, normal form
data Free f a = Pure a
| Bind (f (Free f a))
-- Free monad, Church-encoded form
data ChurchFree f a
= ChurchFree { runChurch :: forall z. (a -> z)
-> (f z -> z)
-> z }
-- Free monad, Scott-encoded form
data Free a = Free { runFree :: forall u . (a -> u)
-> (f (Free f a) -> u)
-> u }
Binding complexity: O(n2
)
<stm/free/stm.h>
Binding complexity: O(n)
<stm/church/stm.h>
(10x faster)
Binding complexity: O(n2
)
41. STML Free monad type (normal form)
-- Free monad, normal form
data Free f a = Pure a
| Bind (f (Free f a))
-- STML Free monad type
type STML a = Free STMF a
42. STML Free monad type (normal form)
-- Free monad, normal form
data Free f a = Pure a
| Bind (f (Free f a))
-- STML Free monad type
type STML a = Free STMF a
f ~ STMF
f (Free f a) ~ STMF (Free STMF a)
f (Free f a) ~ STMF (STML a)
43. STML Free monad type (normal form)
-- Free monad, normal form
data Free f a = Pure a
| Bind (f (Free f a))
-- STML Free monad type
type STML a = Free STMF a
f ~ STMF
f (Free f a) ~ STMF (Free STMF a)
f (Free f a) ~ STMF (STML a)
template <typename Ret>
struct STML {
std::variant<PureF<Ret>, BindF<Ret>> stml;
};
template <typename Ret>
struct PureF {
Ret ret;
};
template <typename Ret>
struct BindF {
STMF<STML<Ret>> stmf;
};