digitalmars.D - Non-Purity of Algebraic opEquals
- =?UTF-8?B?Tm9yZGzDtnc=?= (18/18) Sep 18 2015 Any suggestions on fixing
- =?UTF-8?B?Tm9yZGzDtnc=?= (22/23) Sep 18 2015 I tried tagging up `VariantN` with pure until I got to
- Meta (4/27) Sep 18 2015 It's a long story, but it boils down to the simple fact that
- Jonathan M Davis (14/49) Sep 18 2015 The plan is to remove it from Object and templatize the free
- =?UTF-8?B?Tm9yZGzDtnc=?= (10/17) Sep 18 2015 I'm currently only in need of a VariantN of value-types and
- Steven Schveighoffer (5/17) Sep 18 2015 The issue is not the comparison of the values, it's the comparison of
- Steven Schveighoffer (5/8) Sep 18 2015 Actually, I should qualify this with the fact that I don't really know
- Steven Schveighoffer (4/26) Sep 18 2015 What about type !is typeid(T)?
Any suggestions on fixing http://forum.dlang.org/post/mailman.5452.1422372219.9932.digitalmars-d-bugs puremagic.com I really need `opEquals` in pure unittest { import std.variant : Algebraic; import std.conv : to; auto x = Algebraic!(long, double)(5.to!long); assert(x.hasValue); auto y = x; assert(y == x); } to be pure. This currently fails as t_algebraic.d(11,12): Error: pure function 't_algebraic.__unittestL3_1' cannot call impure function 'std.variant.VariantN!(8LU, long, double).VariantN.opEquals!(VariantN!(8LU, long, double)).opEquals' Ideas anyone?
Sep 18 2015
On Friday, 18 September 2015 at 13:22:14 UTC, Nordlöw wrote:Ideas anyone?I tried tagging up `VariantN` with pure until I got to property inout(T)* peek(T)() inout pure { static if (!is(T == void)) static assert(allowed!(T), "Cannot store a " ~ T.stringof ~ " in a " ~ VariantN.stringof); if (type != typeid(T)) return null; static if (T.sizeof <= size) return cast(inout T*)&store; else return *cast(inout T**)&store; } which then errors as variant.d(701,13): Error: pure function 'std.variant.VariantN!32LU.VariantN.peek!void.peek' cannot call impure function 'object.opEquals' for the line if (type != typeid(T)) Why is `object.opEquals` not pure?
Sep 18 2015
On Friday, 18 September 2015 at 13:53:52 UTC, Nordlöw wrote:On Friday, 18 September 2015 at 13:22:14 UTC, Nordlöw wrote:It's a long story, but it boils down to the simple fact that nobody's gotten around to it yet. I think the plan was to make it templated, but Jonathan Davis knows more about it than anyone.Ideas anyone?I tried tagging up `VariantN` with pure until I got to property inout(T)* peek(T)() inout pure { static if (!is(T == void)) static assert(allowed!(T), "Cannot store a " ~ T.stringof ~ " in a " ~ VariantN.stringof); if (type != typeid(T)) return null; static if (T.sizeof <= size) return cast(inout T*)&store; else return *cast(inout T**)&store; } which then errors as variant.d(701,13): Error: pure function 'std.variant.VariantN!32LU.VariantN.peek!void.peek' cannot call impure function 'object.opEquals' for the line if (type != typeid(T)) Why is `object.opEquals` not pure?
Sep 18 2015
On Friday, 18 September 2015 at 13:55:38 UTC, Meta wrote:On Friday, 18 September 2015 at 13:53:52 UTC, Nordlöw wrote:The plan is to remove it from Object and templatize the free function opEquals which calls opEquals on classes: https://issues.dlang.org/show_bug.cgi?id=9769 Last time I tried to templatize it, compiler bugs got in the way. I need to make another go at it and see what the current status is. But there's a lot of work that has to be done beyond that to actually be able remove the various virtual functions from Object. Regardless, VariantN couldn't have its opEquals explicitly marked with pure, because it's a template and needs to work with types that don't have a pure opEquals. But it _should_ be able to be inferred as pure if the types in question have pure opEquals. However, the situation with Object continues to haunt us. - Jonathan M DavisOn Friday, 18 September 2015 at 13:22:14 UTC, Nordlöw wrote:It's a long story, but it boils down to the simple fact that nobody's gotten around to it yet. I think the plan was to make it templated, but Jonathan Davis knows more about it than anyone.Ideas anyone?I tried tagging up `VariantN` with pure until I got to property inout(T)* peek(T)() inout pure { static if (!is(T == void)) static assert(allowed!(T), "Cannot store a " ~ T.stringof ~ " in a " ~ VariantN.stringof); if (type != typeid(T)) return null; static if (T.sizeof <= size) return cast(inout T*)&store; else return *cast(inout T**)&store; } which then errors as variant.d(701,13): Error: pure function 'std.variant.VariantN!32LU.VariantN.peek!void.peek' cannot call impure function 'object.opEquals' for the line if (type != typeid(T)) Why is `object.opEquals` not pure?
Sep 18 2015
On Friday, 18 September 2015 at 15:40:09 UTC, Jonathan M Davis wrote:Regardless, VariantN couldn't have its opEquals explicitly marked with pure, because it's a template and needs to work with types that don't have a pure opEquals. But it _should_ be able to be inferred as pure if the types in question have pure opEquals. However, the situation with Object continues to haunt us. - Jonathan M DavisI'm currently only in need of a VariantN of value-types and string. Therefore I don't understand why I should need Object.opEquals especially not in the case I gave above where Variant only contains a `long` and a `double`. Is there an easy way to modify `VariantN` to not need `Object.opEquals` when `VariantN` contains only value types and strings?
Sep 18 2015
On 9/18/15 2:05 PM, Nordlöw wrote:On Friday, 18 September 2015 at 15:40:09 UTC, Jonathan M Davis wrote:The issue is not the comparison of the values, it's the comparison of the TypeInfo, which is going to be Object.opEquals no matter what your actual types are. -SteveRegardless, VariantN couldn't have its opEquals explicitly marked with pure, because it's a template and needs to work with types that don't have a pure opEquals. But it _should_ be able to be inferred as pure if the types in question have pure opEquals. However, the situation with Object continues to haunt us.I'm currently only in need of a VariantN of value-types and string. Therefore I don't understand why I should need Object.opEquals especially not in the case I gave above where Variant only contains a `long` and a `double`. Is there an easy way to modify `VariantN` to not need `Object.opEquals` when `VariantN` contains only value types and strings?
Sep 18 2015
On 9/18/15 2:37 PM, Steven Schveighoffer wrote:The issue is not the comparison of the values, it's the comparison of the TypeInfo, which is going to be Object.opEquals no matter what your actual types are.Actually, I should qualify this with the fact that I don't really know how VariantN works :) So I could also be wrong. But your code snippet was comparing TypeInfos. -Steve
Sep 18 2015
On 9/18/15 9:53 AM, Nordlöw wrote:On Friday, 18 September 2015 at 13:22:14 UTC, Nordlöw wrote:What about type !is typeid(T)? This should solve most cases. -SteveIdeas anyone?I tried tagging up `VariantN` with pure until I got to property inout(T)* peek(T)() inout pure { static if (!is(T == void)) static assert(allowed!(T), "Cannot store a " ~ T.stringof ~ " in a " ~ VariantN.stringof); if (type != typeid(T)) return null; static if (T.sizeof <= size) return cast(inout T*)&store; else return *cast(inout T**)&store; } which then errors as variant.d(701,13): Error: pure function 'std.variant.VariantN!32LU.VariantN.peek!void.peek' cannot call impure function 'object.opEquals' for the line if (type != typeid(T)) Why is `object.opEquals` not pure?
Sep 18 2015