www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - mir.algebraic: Visitor cannot be called

reply Andre Pany <andre s-e-a-p.de> writes:
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é
Dec 09 2020
parent reply 9il <ilyayaroshenko gmail.com> writes:
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
Dec 09 2020
parent Andre Pany <andre s-e-a-p.de> writes:
On Thursday, 10 December 2020 at 05:49:12 UTC, 9il wrote:
 On Wednesday, 9 December 2020 at 14:34:18 UTC, Andre Pany wrote:
 [...]
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
Fantastic, thanks a lot! Kind regards André
Dec 09 2020