How do we phase out or limit exceptions, global state, and loops?
A convincing demonstration of correctness being impossible as long as the mechanism is regarded as a black box, our only hope lies in not regarding the mechanism as a black box.
Why would we do this?
The good compiler is a actually a proof assistant; so you can leverage types as propositions.
... Proof Assistant? ...
Types ≃ Propositions ≃ Objects
Terms ≃ Proofs ≃ Morphisms
Curry-Howard(-Lambek) Correspondance.
//In other words:
struct True; // not true: Boolean
We can prove logical statements by constructing elements of types
https://github.com/DanielKrawisz/Truth
Types ≃ Propositions
If you can define the method, you found the proof...
template <typename A, typename B>
struct And {
A fst;
B snd;
};
template <typename A, typename B>
union Or {
A fst;
B snd;
};
template <typename A, typename B>
B Implies(in: A);
Types ≃ Propositions
Updated for C++ 17
template<typename A, typename B>
using And = std::tuple<A, B>;
template<typename A, typename B>
using Or = std::variant<A, B>;
template<typename A, typename B>
using Implies = std::function<B(A)>;
What are we looking to write more of:
Total Functions
Referential Transparency
Proovable Termination
Why: Determinism
Total Functions
Avoid exceptions
int decode(std::string& s);
tl::expected<int, internal_error>
decode(std::string& s);
int use(int a) { return use(a); };
int sum(int... nums) = { return (... + nums); };
Termination
Avoid loops
int use(int a) { while (true) { ... }; return a; };
mlib::lazylist<int> fib = mlib::lazylist::single<int>(0)
.scanLeft(1)([] (int a, int b) { return a + b; });
This subset of your code composes!
Category Theory is the study of composition.
The code your write this ways obeys the laws of category theory.