www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Structural exhaustive matching

reply "Jadbox" <jadit2 gmail.com> writes:
What's the best equivalent to Rust's structural enum/pattern 
(match)ing? Is it also possible to enforce exhaustive matches? 
Basically, I'm curious on what the best way to do ADTs in D.
Apr 21 2015
next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Jadbox:

 I'm curious on what the best way to do ADTs in D.
Sometimes there's no best way, there are several alternative ways with different tradeoffs. D isn't a functional language and there's no really good way to do ADTs in D. You can use plus a "final switch". Or you can use Algebraic from Phobos. Sometimes you can use another Phobos function that simulates an improved switch. Or often you can just give up at using ADTs in D and use what other solutions D offers you (like OOP). Bye, bearophile
Apr 21 2015
prev sibling next sibling parent "weaselcat" <weaselcat gmail.com> writes:
On Tuesday, 21 April 2015 at 15:36:28 UTC, Jadbox wrote:
 What's the best equivalent to Rust's structural enum/pattern 
 (match)ing? Is it also possible to enforce exhaustive matches? 
 Basically, I'm curious on what the best way to do ADTs in D.
D's ADTs are in std.variant, the equivalent of matching is the .visit property AFAIK
Apr 21 2015
prev sibling next sibling parent Justin Whear <justin economicmodeling.com> writes:
On Tue, 21 Apr 2015 15:36:27 +0000, Jadbox wrote:

 What's the best equivalent to Rust's structural enum/pattern (match)ing?
 Is it also possible to enforce exhaustive matches?
 Basically, I'm curious on what the best way to do ADTs in D.
std.variant.Algebraic implements ADTs: import std.variant, std.string; struct Foo { ... } alias A = Algebraic!(int, double, Foo); A a = 1; // std.variant.visit enforces that all possible types are handled, so this // is an error: auto res = a.visit!( (int x) => format("Got an int: %s", x), (double x) => format("Got a double: %s", x), (Foo x) => "Got a Foo" ); You can also dispatch to a function with the appropriate overloads/ template instantiations like so: foreach (T; A.AllowedTypes) if (a.type is typeid(T)) myfunc(a.get!T); This also exhaustively guarantees that myfunc can be called with all possible types of a.
Apr 21 2015
prev sibling next sibling parent Jacob Carlborg <doob me.com> writes:
On 2015-04-21 17:36, Jadbox wrote:
 What's the best equivalent to Rust's structural enum/pattern (match)ing?
 Is it also possible to enforce exhaustive matches? Basically, I'm
 curious on what the best way to do ADTs in D.
There's something call "castSwitch" [1], perhaps not what you're looking for. [1] http://dlang.org/phobos/std_algorithm_comparison.html#.castSwitch -- /Jacob Carlborg
Apr 21 2015
prev sibling parent reply "Martin Nowak" <code dawg.eu> writes:
On Tuesday, 21 April 2015 at 15:36:28 UTC, Jadbox wrote:
 What's the best equivalent to Rust's structural enum/pattern 
 (match)ing? Is it also possible to enforce exhaustive matches? 
 Basically, I'm curious on what the best way to do ADTs in D.
If it needs to be really fast, use final switch on the tag of a discriminated union. enum Tag { A, B, C } struct Val { Tag tag; union { A a; B b; C c; } } void too(Val val) { final switch (val.tag) { case Tag.A: writeln(val.a); break; case Tag.B: writeln(val.b); break; case Tag.C: writeln(val.c); break; } }
Apr 21 2015
parent "weaselcat" <weaselcat gmail.com> writes:
On Wednesday, 22 April 2015 at 04:54:39 UTC, Martin Nowak wrote:
 On Tuesday, 21 April 2015 at 15:36:28 UTC, Jadbox wrote:
 What's the best equivalent to Rust's structural enum/pattern 
 (match)ing? Is it also possible to enforce exhaustive matches? 
 Basically, I'm curious on what the best way to do ADTs in D.
If it needs to be really fast, use final switch on the tag of a discriminated union. enum Tag { A, B, C } struct Val { Tag tag; union { A a; B b; C c; } } void too(Val val) { final switch (val.tag) { case Tag.A: writeln(val.a); break; case Tag.B: writeln(val.b); break; case Tag.C: writeln(val.c); break; } }
there's no reason this should be faster than Algebraic(restricted variant) from std.variant, is there? implementation issue?
Apr 21 2015