Introduction

Open-methods are similar to virtual functions, but they are not required to be members of a class. By being both free and virtual, tdoc/hello_world.adochey provide a 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 also address the banana-gorilla-jungle problem:

The problem with object-oriented languages is they’ve got all this implicit environment that they carry around with them. You wanted a banana but what you got was a gorilla holding the banana and the entire jungle. — Joe Armstrong, creator of Erlang progamming language

As a bonus, open-methods can take more than one argument into account when selecting the appropriate function to call - aka multiple dispatch. For that reason, open-methods are often called multi-methods, but that term is misleading, as it suggests that the feature is useful only when multiple dispatch is needed. In reality, it has been observed that, in large systems written in languages that support multi-methods, most methods use single-dispatch. The real benefit is in the solution to the Expression Problem.

Open-methods were introduced by the Common Lisp Object System, and they are native to many languages: Clojure, Julia, Dylan, TADS, Cecil, Diesel, Nice, etc. 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. I rejected multi-methods with regret because I liked the idea, but couldn’t find an acceptable form under which to accept it. […​] Multi-methods is one of the interesting what-ifs of C++. Could I have designed and implemented them well enough at the time? Would their applications have been important enough to warrant the effort? What other work might have been left undone to provide the time to design and implement 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 and his PhD students Peter Pirkelbauer and Yuriy Solodkyy wrote a series of papers and a prototype implementation based on the EDG compiler. Unfortunately, open-methods never made it into the standard. Stroustrup bemoans, in a more recent paper:

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 ChangingWorld: C++ 2006–2020).

This library implements the features described in the N2216 paper, with some extensions:

  • a mechanism for calling the next most specialized overrider

  • support for smart pointers

  • customization points for RTTI, error handling, tracing, smart pointers…​

Multiple and virtual inheritance are supported, with the exception of repeated inheritance.