Skip to content

Commit 444c60d

Browse files
committed
readme, doc
1 parent ec21cea commit 444c60d

2 files changed

Lines changed: 100 additions & 0 deletions

File tree

README.md

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,96 @@ includes the headers for the compiler, `shared_ptr` and `unique_ptr`. For
1414
example, here is the last iteration of the [AST
1515
example](https://godbolt.org/z/cPjzfanc8) from the tutorial. Don't forget to
1616
turn on optimizations (`-O2 -DNDEBUG`) and to select the Boost library.
17+
18+
## OpenMethod vs Boost.TypeErasure
19+
20+
OpenMethod and TypeErasure exist in the same space: runtime polymorphic systems
21+
that offer a solution to the Expression Problem.
22+
23+
Thanks to BOOST_TYPE_ERASURE_FREE, we can add operations to existing classes,
24+
without the need to modify them. And of course we can add new classes to
25+
existing operations, by providing the required functions on them.
26+
27+
However, we quickly hits a wall, and this is related to the fact that in B.TE
28+
polymorphism is imbued to a "magic" handle, `any`, whereas in OpenMethod,
29+
polymorphism is attached to the object itself.
30+
31+
Let's look at an example. Consider a matrix library, which contains several
32+
matrix subtypes (let's limit ourselves to "ordinary" and "symmetric") and
33+
operations (let's just focus on transposition).
34+
35+
Here is (what I believe is) a plausible design:
36+
37+
```c++
38+
#include <boost/mpl/vector.hpp>
39+
#include <boost/type_erasure/any.hpp>
40+
#include <boost/type_erasure/free.hpp>
41+
#include <boost/type_erasure/typeid_of.hpp>
42+
#include <boost/core/demangle.hpp>
43+
#include <iostream>
44+
45+
namespace mpl = boost::mpl;
46+
using namespace boost::type_erasure;
47+
48+
BOOST_TYPE_ERASURE_FREE(transpose);
49+
50+
struct ordinary_matrix_impl {
51+
virtual ~ordinary_matrix_impl() { /* ... */ }
52+
std::size_t rows, cols;
53+
std::vector<double> elements; // rows x cols doubles
54+
};
55+
56+
struct symmetric_matrix_impl {
57+
virtual ~symmetric_matrix_impl() { /* ... */ }
58+
std::size_t rows; // cols == rows
59+
std::vector<double> elements; // rows doubles
60+
};
61+
62+
struct matrix {
63+
any<mpl::vector<copy_constructible<>, has_transpose<matrix(_self&)>, typeid_<>>> impl;
64+
};
65+
66+
auto transpose(matrix m) {
67+
return transpose(m.impl);
68+
}
69+
70+
auto transpose(ordinary_matrix_impl& m) {
71+
return matrix{ordinary_matrix_impl()};
72+
}
73+
74+
auto transpose(symmetric_matrix_impl& m) {
75+
return matrix{m};
76+
}
77+
78+
auto main() -> int {
79+
{
80+
matrix m{ordinary_matrix_impl()};
81+
auto t = transpose(m);
82+
std::cout << boost::core::demangle(typeid_of(t.impl).name()) << "\n";
83+
// ordinary_matrix_impl
84+
}
85+
86+
{
87+
matrix m{symmetric_matrix_impl()};
88+
auto t = transpose(m);
89+
std::cout << boost::core::demangle(typeid_of(t.impl).name()) << "\n";
90+
// symmetric_matrix_impl
91+
}
92+
93+
return 0;
94+
}
95+
```
96+
97+
([Compiler Explorer](https://godbolt.org/z/613Eo5zGP)
98+
99+
We were able to add new behavior to existing classes (the "impl" classes)
100+
without needing to modify them. This is promising.
101+
102+
Here is the equivalent using open-methods:
103+
104+
```c++
105+
```
106+
107+
108+
109+
We can also add serialization to JSON:

doc/introduction.adoc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@ the Expression Problem:
99
to add new operations on the existing types, and new types to the existing
1010
operations, without modifying existing code?
1111

12+
Open-methods also offer a solution to the banana-gorilla-jungle problem:
13+
14+
> The problem with object-oriented languages is they’ve got all this implicit
15+
environment that they carry around with them. You wanted a banana but what you
16+
got was a gorilla holding the banana and the entire jungle. — Joe Armstrong,
17+
creator of Erlang progamming language
18+
1219
As a bonus, open-methods can take more than one argument into account when
1320
selecting the appropriate function to call - aka multiple dispatch. For that
1421
reason, open-methods are often called multi-methods, but that term is

0 commit comments

Comments
 (0)