Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does Raku deal with the diamond problem (multiple inheritance)?

So it's no secret that Raku has multiple inheritance, so that got me wondering: "how does Raku deal with that in any reasonable manner?"

Some preliminary testing reveals that default behaviour is inherited from the first class in the inheritance list, that's fine, many other languages do it like that too

class A {
    has $.foo = 0;

    method speak {...}
}

class B is A {
    has $.foo = 1;

    method speak {
        say 'moo';
    }
}

class C is A {
    has $.foo = 2;

    method speak {
        say 'baa';
    }
}

class D is B is C {}

class E is C is B {}

say D.new.foo; # prints 1 (from B)
say E.new.foo; # prints 2 (from C)

But that got me wondering, what if I want D to use C's speak? Due to the inheritance order I get B's by default.

I understand that roles exist to solve this exact issue by facilitating a disambiguation mechanism, but suppose hypothetically I find myself in a situation where I don't have roles at my disposal (boss hates them, inherited a library that doesn't have them, pick your excuse) and really need to disambiguate the inherited classes.

What's the mechanism for dealing with that in Raku?

like image 743
Electric Coffee Avatar asked Jun 04 '20 07:06

Electric Coffee


People also ask

How can we solve diamond problem in inheritance?

The Diamond Problem is fixed using virtual inheritance, in which the virtual keyword is used when parent classes inherit from a shared grandparent class. By doing so, only one copy of the grandparent class is made, and the object construction of the grandparent class is done by the child class.

What is diamond problem in multiple inheritance?

The "diamond problem" (sometimes referred to as the "Deadly Diamond of Death") is an ambiguity that arises when two classes B and C inherit from A, and class D inherits from both B and C.

What is diamond problem in case of multiple inheritance in Java?

Diamond Problem in Java This leads to the ambiguity as the compiler doesn't know which superclass method to execute. Because of the diamond-shaped class diagram, it's referred to as Diamond Problem in java. The diamond problem in Java is the main reason java doesn't support multiple inheritances in classes.

What is diamond problem how can we handle this problem explain with example?

The diamond problem The diamond problem occurs when two superclasses of a class have a common base class. For example, in the following diagram, the TA class gets two copies of all attributes of Person class, this causes ambiguities. For example, consider the following program.


1 Answers

Generally you would need to provide a tie-breaker method in the class that has the (potential) ambiguity. Fortunately, you do not have to create separate methods, as you can call specific versions of methods in a call.

So the answer to your question: Add a method speak to class D, and have that call the speak method from class C:

class D {
    ...
    method speak { self.C::speak }
}

And for methods taking parameters, take a Capture of all parameters, and pass that on:

class D {
    ...
    method foo(|c) { self.C::foo(|c) }
}

Note that the "c" in |c is just an identifier, it could be any identifier. But it is sorta customary, at least with Raku core developers, to just use |c, with the "c" standing for "capture".

Now, this will cause some overhead, as you would have an extra level of indirection. Should this turn out to be a performance issue, there's some meta-programming you can do to alias the speak method in D to the speak method in C:

class D {
    ...
    BEGIN D.^add_method("speak",C.^find_method("speak"));
}

This will, at compile time because of the BEGIN, add a Method object to the D class called speak that is defined by the speak method of class C. Since this is an alias, you don't have to worry about any parameters being passed.

like image 101
Elizabeth Mattijsen Avatar answered Sep 19 '22 18:09

Elizabeth Mattijsen