
Hello Boost developers! I would like to propose my open-method library for inclusion in Boost. Open-methods are an elegant solution to the Expression Problem:
Given a set of types, and a set of operations on these types, is it possible to add new operations on the existing types, and new types to the existing operations, without modifying existing code?
Open-methods solve the Expression Problem by making it possible to define free virtual functions, i.e. virtual functions that exist outside of a class. They also help reduce coupling. Open-methods are often called "multi-methods", because they typically make it possible to select an overrider on the basis of more than one argument (as this library does). Nice, but this is a distraction. Observations show that single dispatch largely outnumbers multiple dispatch in real systems, even in languages that natively support multi-methods (Common Lisp, Clojure, Julia, Dylan, TADS, Cecil, Diesel, Nice, etc). "Multi" is just the cherry on the "open" cake. Bjarne Stroustrup wanted open-methods in C++ almost from the beginning. In D&E he writes:
I repeatedly considered a mechanism for a virtual function call based on more than one object, often called multi-methods. [...] Since about 1985, I have always felt some twinge of regret for not providing multi-methods. Stroustrup, 1994, The Design and Evolution of C++, 13.8.
Circa 2007, he tried to bring open-methods into the standard, unfortunately without success, to his enduring regret. Decades later he writes:
In retrospect, I don’t think that the object-oriented notation (e.g., x.f(y)) should ever have been introduced. The traditional mathematical notation f(x,y) is sufficient. As a side benefit, the mathematical notation would naturally have given us multi-methods, thereby saving us from the visitor pattern workaround. Stroustrup, 2020, Thriving in a Crowded and Changing World: C++ 2006–2020.
This is what this library is all about: f(x, y), and getting rid of visitors. It closely follows the design described in the papers by Stroustrup and his PhD students Peter Pirkelbauer and Yuriy Solodkyy. Method dispatch is *fast*. It uses v-tables similar to native virtual functions, and it can match their performance. The library also provides additional features: a mechanism to call the next most specialized overrider, support for smart pointers, customization points for alternative RTTI systems, error handling, tracing, etc. The library requires C++17 or above. It supports virtual and multiple inheritance, excluding repeated inheritance. For evaluation purposes, I prepared a repository with a library adapted to Boost naming conventions: https://github.com/jll63/Boost.OpenMethod. The documentation is here: https://jll63.github.io/Boost.OpenMethod. Here are a few examples from the tutorial on Compiler Explorer: * Hello World: https://godbolt.org/z/9hv8oE8zd * AST - combining virtual_ptr and std::unique_ptr: https://godbolt.org/z/cPjzfanc8 * Intrusive vptr: https://godbolt.org/z/87h9zv7dK * Policy for throwing exceptions: https://godbolt.org/z/nEYWGsPc5 If you like what you see, please consider endorsing the library. Thanks, Jean-Louis Leroy