Thread overview | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
May 07, 2020 variant visit not pure? | ||||
---|---|---|---|---|
| ||||
Good morning, Is there a reason why std.variant.visit is not inferring pure? ``` void test() pure { Algebraic!(int, string) alg; visit!( (string) => 0, (int) => 0)(alg); } Error: pure function test cannot call impure function test.visit!(VariantN!(16LU, int, string)).visit ``` Thank you |
May 07, 2020 Re: variant visit not pure? | ||||
---|---|---|---|---|
| ||||
Posted in reply to learner | On Thursday, 7 May 2020 at 09:22:28 UTC, learner wrote: > Good morning, > > Is there a reason why std.variant.visit is not inferring pure? > I think `variant` will not infer any trributes. I'm not sure why. It could be some language limitation (that's the reason why `std.range.enumerate` does not infer attributes for example). Or it could be just badly implemented. Either way, there are DUB packages that are better in this (and other) regards. I recommend Taggedalgebraic[1]. [1] https://code.dlang.org/packages/taggedalgebraic |
May 07, 2020 Re: variant visit not pure? | ||||
---|---|---|---|---|
| ||||
Posted in reply to learner | On Thursday, 7 May 2020 at 09:22:28 UTC, learner wrote: > Good morning, > > Is there a reason why std.variant.visit is not inferring pure? > > ``` > void test() pure { > Algebraic!(int, string) alg; > visit!( (string) => 0, (int) => 0)(alg); > } > > Error: pure function test cannot call impure function test.visit!(VariantN!(16LU, int, string)).visit > ``` std.variant.Algebraic is essentially a std.variant.Variant in different clothes. Variant is very flexible, and this comes at a cost (and isn't used in Algebraic, meaning you pay for things you don't use). Like Dukc said, you might be better off with Taggedalgebraic or SumType (https://code.dlang.org/packages/sumtype). Variant uses runtime type information to hold *any* type. Since Algebraic specifically only holds a few types, all the framework that's in place for Variant is wasted on Algebraic, and makes it less useful and less performant. -- Simen |
May 07, 2020 Re: variant visit not pure? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen Kjærås | On Thursday, 7 May 2020 at 10:41:01 UTC, Simen Kjærås wrote: > On Thursday, 7 May 2020 at 09:22:28 UTC, learner wrote: >> Good morning, >> >> Is there a reason why std.variant.visit is not inferring pure? >> >> ``` >> void test() pure { >> Algebraic!(int, string) alg; >> visit!( (string) => 0, (int) => 0)(alg); >> } >> >> Error: pure function test cannot call impure function test.visit!(VariantN!(16LU, int, string)).visit >> ``` > > std.variant.Algebraic is essentially a std.variant.Variant in different clothes. Variant is very flexible, and this comes at a cost (and isn't used in Algebraic, meaning you pay for things you don't use). Like Dukc said, you might be better off with Taggedalgebraic or SumType (https://code.dlang.org/packages/sumtype). > > > Variant uses runtime type information to hold *any* type. Since Algebraic specifically only holds a few types, all the framework that's in place for Variant is wasted on Algebraic, and makes it less useful and less performant. > > -- > Simen Thank you Simon and Dukc, I've find this: https://issues.dlang.org/show_bug.cgi?id=16662 So, it seems that Phobos isn't in a good shape ... what a pity! |
May 07, 2020 Re: variant visit not pure? | ||||
---|---|---|---|---|
| ||||
Posted in reply to learner | On Thursday, 7 May 2020 at 13:17:21 UTC, learner wrote:
> I've find this: https://issues.dlang.org/show_bug.cgi?id=16662
Hmm, that explains why it can't infer attributes. An unlimited variant could contain an object, and using it might or might not be <insert attribute here>.
Of course, it could still infer the attribute for algebraic types were the wrapper a bit smarter. But `Algebraic` is inferior to the DUB packages anyway. Bad performance like Simen said, and can always be `null` regardless of requested types. With Taggedalgebraic, you can insert `Void` to allowed types if you want `null` value but you don't have it just because.
|
May 07, 2020 Re: variant visit not pure? | ||||
---|---|---|---|---|
| ||||
Posted in reply to learner | On 5/7/20 5:22 AM, learner wrote:
> Good morning,
>
> Is there a reason why std.variant.visit is not inferring pure?
>
> ```
> void test() pure {
> Algebraic!(int, string) alg;
> visit!( (string) => 0, (int) => 0)(alg);
> }
>
> Error: pure function test cannot call impure function test.visit!(VariantN!(16LU, int, string)).visit
> ```
>
> Thank you
Because VariantN (the base of Algebraic) can literally hold anything, it cannot be pure, @safe, nothrow, @nogc.
As others have recommended, I suggest using TaggedAlgebraic. I recently have been using it to create an algebraic type to hold a MYSQL value, so I can migrate the mysql-native library to be @safe (mysql-native currently uses Variant for everything).
I added a special UDA to TaggedAlgebraic, so you can guarantee only @safe calls are allowed (for instance, if it can hold a pointer and an int, then opBinary!"+" can be marked as @safe if the operation fails when it's a pointer).
TaggedAlgebraic could probably do the same for pure, but not sure about nothrow and @nogc, since it uses exceptions when things aren't valid.
-Steve
|
May 07, 2020 Re: variant visit not pure? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Thursday, 7 May 2020 at 14:53:10 UTC, Steven Schveighoffer wrote:
> As others have recommended, I suggest using TaggedAlgebraic. I recently have been using it to create an algebraic type to hold a MYSQL value, so I can migrate the mysql-native library to be @safe (mysql-native currently uses Variant for everything).
>
> -Steve
I've been using SumType... What are the main differences between it and TaggedAlgebraic?
|
May 07, 2020 Re: variant visit not pure? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ben Jones | On Thursday, 7 May 2020 at 15:36:36 UTC, Ben Jones wrote: > On Thursday, 7 May 2020 at 14:53:10 UTC, Steven Schveighoffer wrote: > >> As others have recommended, I suggest using TaggedAlgebraic. I recently have been using it to create an algebraic type to hold a MYSQL value, so I can migrate the mysql-native library to be @safe (mysql-native currently uses Variant for everything). >> >> -Steve > > I've been using SumType... What are the main differences between it and TaggedAlgebraic? As far as I can tell, there are two main differences: 1. TaggedAlgebraic has some convenient operator overloads that can assert at runtime if called improperly (i.e., when the contained type does not support the operation). SumType never asserts at runtime, and instead requires you to use `match` for these operations to ensure that they are only performed on the appropriate types. 2. TaggedAlgebraic requires you to declare a union type as a "base", whereas SumType takes the list of member types directly as template arguments. If you want more detailed information, both have online documentation: TaggedAlgebraic: https://vibed.org/api/taggedalgebraic.taggedalgebraic/ SumType: https://pbackus.github.io/sumtype/sumtype.html |
May 07, 2020 Re: variant visit not pure? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Thursday, 7 May 2020 at 14:53:10 UTC, Steven Schveighoffer wrote:
> On 5/7/20 5:22 AM, learner wrote:
>> [...]
>
> Because VariantN (the base of Algebraic) can literally hold anything, it cannot be pure, @safe, nothrow, @nogc.
>
> As others have recommended, I suggest using TaggedAlgebraic. I recently have been using it to create an algebraic type to hold a MYSQL value, so I can migrate the mysql-native library to be @safe (mysql-native currently uses Variant for everything).
>
> I added a special UDA to TaggedAlgebraic, so you can guarantee only @safe calls are allowed (for instance, if it can hold a pointer and an int, then opBinary!"+" can be marked as @safe if the operation fails when it's a pointer).
>
> TaggedAlgebraic could probably do the same for pure, but not sure about nothrow and @nogc, since it uses exceptions when things aren't valid.
>
> -Steve
Modules of D standard library aren't in a good shape, if everyone suggests alternatives for a basic building block as variant.
The types VariantN can hold are known at compile time, why can't it be specialized?
|
May 08, 2020 Re: variant visit not pure? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dukc | On Thursday, 7 May 2020 at 10:21:26 UTC, Dukc wrote:
>
> that's the reason why `std.range.enumerate` does not infer attributes for example
This was wrong. `enumerate` can infer. It's `lockstep` that cannot.
|
Copyright © 1999-2021 by the D Language Foundation