Software Engineering Asked by Maggyero on July 23, 2020
C++ only supports single dynamic dispatch methods. Indeed, the following C++ program:
#include <iostream>
struct Shape {
virtual void overlap(Shape* y) { std::cout << "Shape, Shape" << std::endl; }
};
struct Circle: Shape {
void overlap(Shape* y) { std::cout << "Circle, Shape" << std::endl; }
void overlap(Circle* y) { std::cout << "Circle, Circle" << std::endl; }
};
void overlap(Shape* x, Shape* y) { std::cout << "Shape, Shape" << std::endl; }
void overlap(Circle* x, Shape* y) { std::cout << "Circle, Shape" << std::endl; }
void overlap(Circle* x, Circle* y) { std::cout << "Circle, Circle" << std::endl; }
int main() {
Shape* x = new Circle();
Shape* y = new Circle();
x->overlap(y);
overlap(x, y);
return 0;
}
outputs:
Circle, Shape
Shape, Shape
If C++ supported multiple dynamic dispatch methods (i.e. bound to classes) and multiple dynamic dispatch functions (i.e. not bound to classes), the previous program would output:
Circle, Circle
Circle, Circle
Common Lisp, Dylan and Julia support multiple dynamic dispatch functions but do not support methods (single or multiple dynamic dispatch).
Would it be possible for a language to support multiple dynamic dispatch methods instead of or in addition to multiple dynamic dispatch functions?
I am asking this because supporting only multiple dynamic dispatch functions look like a step backward to procedural programming. Encapsulation (implementation hiding behind an interface) is a pillar of object-oriented programming. Using functions in place of methods forces the exposure of the supposedly hidden states of objects to be able to manipulate them, because contrary to methods, functions do not have a privileged access to these states.
There are lots of work-arounds to implement multi-methods in languages that don't support them:
Since there are known solutions to implement it, it can for sure be automated and build into the language.
The design sacrifice of both the Open/Close principle, but also the principle of least knowledge is in my view the main reason why there are not much languages that offer what you expect.
Your example
Take the example of your overlap()
and imagine there would be a way to add multi-methods (i.e. methods in the class and not free-standaing functions):
Shape
Circle
Triangle
and Retangle
.Shape
, for example Octopus
: how would this interact with your library: the user will not be able to change your library (close) - how can he/she extend it?In your example, finding the overlap is in fact not the concern of one single class, but of two classes together. Adding a new class that intervenes in this dynamic, requires to define new couples of possible interactions. So in the end the interaction belongs not to the class, but to the context that knows about the potential classes in presence.
And if you consider the problem under this angle, the existing solution already offered for multiple-dipatch in C# seems to be the most promising to go.
Correct answer by Christophe on July 23, 2020
This is basically a fundamentally impossible problem:
The fundamental idea of multiple dispatch is that all arguments that take part in the dispatch are equal, i.e. that there is no argument which is "special". So, if you don't want a "special" argument, then you only have two choices: you either have privileged access to no arguments, or you have privileged access to all arguments.
The former case is what you are complaining about, but the latter case means that you get privileged access to objects that you don't own, thus breaking object-oriented encapsulation.
The fundamental idea of object-oriented encapsulation is that an object only has privileged access to itself. It doesn't even have privileged access to other instances of the same type, unlike Abstract Data Types. (That, by the way, is why instances of class
es in Java are not objects, only instances of interface
s are objects.)
So, by the very definition of Object-Orientation, there can only ever be at most one "special" argument.
I remember reading a research paper on adding Multimethods to single-dispatch OO languages using so-called Tuple Classes. The idea was that you can define a class something like this:
tuple struct (Circle x, Circle y) {
void overlap() { std::cout << "Circle, Circle" << std::endl; }
}
But the whole point of doing it this way was that methods in the Tuple Class (Circle x, Circle y)
can only interact with the public API of x
and y
precisely because they are not defined by the original authors of Circle
and thus shouldn't have privileged access.
Otherwise, I could simply define a Tuple Class
tuple struct (DoesntMatterWhatIPutHere x, SuperSecureCreditProcessor l33th4X0r) {
void emailMeThePins() { std::cout << l33th4X0r.getPin(); }
}
Answered by Jörg W Mittag on July 23, 2020
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP