Thread overview | |||||
---|---|---|---|---|---|
|
December 09, 2020 mir.algebraic: Visitor cannot be called | ||||
---|---|---|---|---|
| ||||
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é |
December 10, 2020 Re: mir.algebraic: Visitor cannot be called | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andre Pany | 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
|
December 10, 2020 Re: mir.algebraic: Visitor cannot be called | ||||
---|---|---|---|---|
| ||||
Posted in reply to 9il | 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é
|
Copyright © 1999-2021 by the D Language Foundation