On Wednesday, 9 December 2020 at 14:34:18 UTC, Andre Pany wrote:
Hi,

I want to port some Python coding and try have as much similiar coding as
possible.

I thought I can have a mir variant which stores either class A or B
and I can call at runtime a method like this:

```
/+ dub.sdl:
        name "app"
        dependency "mir-core" version="1.1.51"
+/

import std.stdio: writeln;
import mir.algebraic;

class A {
        void foo(int i){writeln("A.foo");}
}

class B {
        void foo(int i, string s){writeln("B.foo");}
}

void main() {
        Variant!(A,B) v = new A();
        v.foo(3);
}
```

But it fails with:
Error: static assert: "Algebraic!(A, B): the visitor cann't be caled with arguments (B, int)"

The error message seems strange. Is the behavior I want somehow possible? (At runtime I know whether I have an object of A or B and will only call
with the correct method signature).

Kind regards
André

For .member access mir.algebraic checks at compile time that all underlying types (except typeof(null)) can be called with provided arguments. It is kind of API protection.

Alternatives:

With compile-time known type
```
v.get!A.foo(3); // will throw if it isn't A
v.trustedGet!A.foo(3); // will assert if it isn't A
```

Without compile-time known type
```
v.tryGetMember!"foo"(3); // will throw if it isn't A
v.optionalGetMember!"foo"(3); // will return null Nullable!void of it isn't A
```

tryGetMember and optionalGetMember are alternative visitor handlers in mir.algebraic.

Kind regards,
Ilya

Reply via email to