mir.algebraic: Visitor cannot be called

9il ilyayaroshenko at gmail.com
Thu Dec 10 05:49:12 UTC 2020


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



More information about the Digitalmars-d-learn mailing list