www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.announce - sumtype 0.3.0

reply Paul Backus <snarwin gmail.com> writes:
SumType is a generic sum type for modern D. It is meant as an 
alternative to `std.variant.Algebraic`.

Features:
   - Pattern matching, including support for structural matching 
(*)
   - Self-referential types, using `This`
   - Works with `pure`, ` safe`, ` nogc`, and `immutable` (*)
   - Zero runtime overhead compared to hand-written C
     - No heap allocation
     - Does not rely on runtime type information (`TypeInfo`) (*)

Starred features (*) are those that are missing from `Algebraic`.

Code examples are available in the documentation (linked below).

New in this release:
   - The list of types allowed in a sum type is now public
   - Implicit qualifier conversions are now allowed in pattern 
matching
   - Better code examples in the documentation

This library is a work in progress. If you have a use case you'd 
like to see supported, or an API you'd like to see implemented, 
please get in touch!

Documentation: https://pbackus.github.io/sumtype/sumtype.html
DUB: https://code.dlang.org/packages/sumtype
Github: https://github.com/pbackus/sumtype
May 06
next sibling parent "Nick Sabalausky (Abscissa)" <SeeWebsiteToContactMe semitwist.com> writes:
On 05/06/2018 03:18 PM, Paul Backus wrote:
 SumType is a generic sum type for modern D. It is meant as an 
 alternative to `std.variant.Algebraic`.
 
Very nice! I may use this.
May 06
prev sibling next sibling parent Per =?UTF-8?B?Tm9yZGzDtnc=?= <per.nordlow gmail.com> writes:
On Sunday, 6 May 2018 at 19:18:02 UTC, Paul Backus wrote:
 SumType is a generic sum type for modern D. It is meant as an 
 alternative to `std.variant.Algebraic`.

 Features:
   - Pattern matching, including support for structural matching 
 (*)
   - Self-referential types, using `This`
   - Works with `pure`, ` safe`, ` nogc`, and `immutable` (*)
   - Zero runtime overhead compared to hand-written C
     - No heap allocation
     - Does not rely on runtime type information (`TypeInfo`) (*)

 Starred features (*) are those that are missing from 
 `Algebraic`.

 Code examples are available in the documentation (linked below).

 New in this release:
   - The list of types allowed in a sum type is now public
   - Implicit qualifier conversions are now allowed in pattern 
 matching
   - Better code examples in the documentation

 This library is a work in progress. If you have a use case 
 you'd like to see supported, or an API you'd like to see 
 implemented, please get in touch!

 Documentation: https://pbackus.github.io/sumtype/sumtype.html
 DUB: https://code.dlang.org/packages/sumtype
 Github: https://github.com/pbackus/sumtype
Nice. I've written something similar in LightAlgebraic at https://github.com/nordlow/phobos-next/blob/master/src/vary.d#L30 which is also significantly faster than `std.typecons.Algebraic`. Has the same features as SumType except for - Self-referential types, using `This` and - pattern matching Note that the `memoryPacked` flag being `true` hasn't been thoroughly tested. Your're free to copy an ideas or features in `LightAlgebraic` into `SumType`.
May 06
prev sibling next sibling parent reply Brian Schott <briancschott gmail.com> writes:
On Sunday, 6 May 2018 at 19:18:02 UTC, Paul Backus wrote:
 SumType is a generic sum type for modern D. It is meant as an 
 alternative to `std.variant.Algebraic`.

 Features:
   - Pattern matching, including support for structural matching 
 (*)
   - Self-referential types, using `This`
   - Works with `pure`, ` safe`, ` nogc`, and `immutable` (*)
   - Zero runtime overhead compared to hand-written C
     - No heap allocation
     - Does not rely on runtime type information (`TypeInfo`) (*)

 Starred features (*) are those that are missing from 
 `Algebraic`.

 Code examples are available in the documentation (linked below).

 New in this release:
   - The list of types allowed in a sum type is now public
   - Implicit qualifier conversions are now allowed in pattern 
 matching
   - Better code examples in the documentation

 This library is a work in progress. If you have a use case 
 you'd like to see supported, or an API you'd like to see 
 implemented, please get in touch!

 Documentation: https://pbackus.github.io/sumtype/sumtype.html
 DUB: https://code.dlang.org/packages/sumtype
 Github: https://github.com/pbackus/sumtype
I spent several hours trying to get this working with a non-trivial AST, and I think that it just isn't going to work until the compiler front-end gets better about handling recursive definitions. It fails in more-or-less the same way that my attempts at using std.variant did, and this is not the fault of your library. It's too bad, because the visitor pattern is not very good when you want to support visitors that should not accidentally modify the tree (i.e. arguments to `visit` are `const`), and other visitors whose job is to re-write the tree.
May 07
parent Paul Backus <snarwin gmail.com> writes:
On Monday, 7 May 2018 at 09:23:04 UTC, Brian Schott wrote:
 I spent several hours trying to get this working with a 
 non-trivial AST, and I think that it just isn't going to work 
 until the compiler front-end gets better about handling 
 recursive definitions. It fails in more-or-less the same way 
 that my attempts at using std.variant did, and this is not the 
 fault of your library.

 It's too bad, because the visitor pattern is not very good when 
 you want to support visitors that should not accidentally 
 modify the tree (i.e. arguments to `visit` are `const`), and 
 other visitors whose job is to re-write the tree.
Thanks for taking a look! There are definitely compiler issues that keep this (and Algebraic) from being as useful as they could be (e.g., issue 1807 [1]), though so far, I've managed to find workarounds for the ones I ran into. I'd be curious to see the code that was giving you trouble, if you still have it. [1]: https://issues.dlang.org/show_bug.cgi?id=1807
May 07
prev sibling next sibling parent Atila Neves <atila.neves gmail.com> writes:
On Sunday, 6 May 2018 at 19:18:02 UTC, Paul Backus wrote:
 SumType is a generic sum type for modern D. It is meant as an 
 alternative to `std.variant.Algebraic`.

 Features:
   - Pattern matching, including support for structural matching 
 (*)
   - Self-referential types, using `This`
   - Works with `pure`, ` safe`, ` nogc`, and `immutable` (*)
   - Zero runtime overhead compared to hand-written C
     - No heap allocation
     - Does not rely on runtime type information (`TypeInfo`) (*)

 Starred features (*) are those that are missing from 
 `Algebraic`.

 Code examples are available in the documentation (linked below).

 New in this release:
   - The list of types allowed in a sum type is now public
   - Implicit qualifier conversions are now allowed in pattern 
 matching
   - Better code examples in the documentation

 This library is a work in progress. If you have a use case 
 you'd like to see supported, or an API you'd like to see 
 implemented, please get in touch!

 Documentation: https://pbackus.github.io/sumtype/sumtype.html
 DUB: https://code.dlang.org/packages/sumtype
 Github: https://github.com/pbackus/sumtype
Yeeeees. I love it when someone else goes and implements something that was on my TODO stack. Dmitry Olshansky did it last week with Photon, then you come along and take another item from me as well. Less work for me! Good work, definitely going to try this out.
May 07
prev sibling next sibling parent reply =?UTF-8?Q?S=c3=b6nke_Ludwig?= <sludwig+d outerproduct.org> writes:
Another similar project: http://taggedalgebraic.dub.pm/
May 07
next sibling parent drug <drug2004 bk.ru> writes:
On 07.05.2018 22:28, Sönke Ludwig wrote:
 Another similar project: http://taggedalgebraic.dub.pm/
And it's pretty nice one. I use it for couple of years.
May 07
prev sibling parent reply Paul Backus <snarwin gmail.com> writes:
On Monday, 7 May 2018 at 19:28:16 UTC, Sönke Ludwig wrote:
 Another similar project: http://taggedalgebraic.dub.pm/
There's also tagged_union and minivariant on dub, that I've found. I'm definitely far from the first person to be dissatisfied with `Algebraic`, or to try my hand at writing a replacement. The main difference between all of those and sumtype is that sumtype has pattern matching. Personally, I consider that an essential feature--arguably *the* essential feature--which is why I went ahead with Yet Another implementation anyway.
May 07
next sibling parent "Nick Sabalausky (Abscissa)" <SeeWebsiteToContactMe semitwist.com> writes:
On 05/07/2018 05:35 PM, Paul Backus wrote:
 
 Personally, I consider [pattern matching] an essential 
 feature--arguably *the* essential feature--
After having used Nemerle, I tend to agree. I haven't gotten around to using this yet, but I did take a look at the source and was blown away by how small and simple it is. Kudos! Oh, and I love that it's much easier to remember how to spell than "Algebraic" :) That said, it would be really nice if D made it possible for a tool like this to support more things being defined in-line. For example, in Nemerle, it's possible to define a binary tree like this: --------------------------------- // Mainly from: // https://github.com/rsdn/nemerle/wiki/Grok-Variants-and-matching variant Tree { | Node { left : Tree; elem : int; right : Tree; } | EmptyLeaf } --------------------------------- But AFAIK, in D, each part would have to be defined separately, making the overall structure less clear: --------------------------------- struct Node { Tree* left; int elem; Tree* right; } struct EmptyLeaf {} alias Tree = SumType!(Node, EmptyLeaf); --------------------------------- Of course, that's not your lib's fault, just an unfortunate limitation of D.
May 08
prev sibling parent Atila Neves <atila.neves gmail.com> writes:
On Monday, 7 May 2018 at 21:35:44 UTC, Paul Backus wrote:
 On Monday, 7 May 2018 at 19:28:16 UTC, Sönke Ludwig wrote:
 Another similar project: http://taggedalgebraic.dub.pm/
There's also tagged_union and minivariant on dub, that I've found. I'm definitely far from the first person to be dissatisfied with `Algebraic`, or to try my hand at writing a replacement. The main difference between all of those and sumtype is that sumtype has pattern matching. Personally, I consider that an essential feature--arguably *the* essential feature--which is why I went ahead with Yet Another implementation anyway.
I agree - it's the same reason I was going to write one. But now I don't have to. :) Atila
May 09
prev sibling next sibling parent reply TheGag96 <thegag96 gmail.com> writes:
On Sunday, 6 May 2018 at 19:18:02 UTC, Paul Backus wrote:
 snip
Wow.. without comments and unittests, the implementation is only 116 lines. Awesome job. Even now I still find it incredible what D can do. Is Algebraic in the standard library really that bad? And if so, why aren't implementations like this being accepted?
May 07
parent Paul Backus <snarwin gmail.com> writes:
On Tuesday, 8 May 2018 at 06:33:38 UTC, TheGag96 wrote:
 Wow.. without comments and unittests, the implementation is 
 only 116 lines. Awesome job. Even now I still find it 
 incredible what D can do. Is Algebraic in the standard library 
 really that bad? And if so, why aren't implementations like 
 this being accepted?
Thanks! Algebraic isn't terrible, but it has one significant design flaw, which is that it shares its implementation with Variant. Variant doesn't have a fixed list of allowed types, so it requires a much more complex implementation than just a union and an integer tag. By sharing that implementation, Algebraic inherits all the costs of its complexity without getting any of the benefits. I've never contributed to Phobos, so someone with more experience may have better insight here, but my guess is that changing Algebraic at this point would break too much code to be worth the trouble. Perhaps when sumtype is more mature, though, a case could be made for including it in a separate module.
May 08
prev sibling next sibling parent reply jmh530 <john.michael.hall gmail.com> writes:
On Sunday, 6 May 2018 at 19:18:02 UTC, Paul Backus wrote:
 [snip]
   - Zero runtime overhead compared to hand-written C
Just to clarify, would the run-time performance of the length function in the example be equivalent to if it had been specialized for the Rectangular types (e.g. double length(Rectacular r) { ... })? It looks like the match is using compile-time functionality to choose the right function to call, but I wanted to be sure.
May 09
parent reply Paul Backus <snarwin gmail.com> writes:
On Wednesday, 9 May 2018 at 13:33:44 UTC, jmh530 wrote:
 On Sunday, 6 May 2018 at 19:18:02 UTC, Paul Backus wrote:
 [snip]
   - Zero runtime overhead compared to hand-written C
Just to clarify, would the run-time performance of the length function in the example be equivalent to if it had been specialized for the Rectangular types (e.g. double length(Rectacular r) { ... })? It looks like the match is using compile-time functionality to choose the right function to call, but I wanted to be sure.
What length actually does, after all the compile-time stuff is expanded, is essentially this: switch(v.tag) { case 0: return sqrt(v.value!Rectangular.x**2 + v.value!Rectangular.y**2); case 1: return v.value!Polar.r; } It's the same thing you'd get if you were implementing a tagged union by hand in C. It's not exactly the same as a function specialized for Rectangular, because the entire point of a sum type or tagged union is to allow runtime dispatch based on the tag. However, the process of choosing which function goes with which tag takes place entirely at compile time.
May 09
parent jmh530 <john.michael.hall gmail.com> writes:
On Wednesday, 9 May 2018 at 14:56:20 UTC, Paul Backus wrote:
 [snip]

 What length actually does, after all the compile-time stuff is 
 expanded, is essentially this:

 switch(v.tag)
 {
     case 0: return sqrt(v.value!Rectangular.x**2 + 
 v.value!Rectangular.y**2);
     case 1: return v.value!Polar.r;
 }

 It's the same thing you'd get if you were implementing a tagged 
 union by hand in C.

 It's not exactly the same as a function specialized for 
 Rectangular, because the entire point of a sum type or tagged 
 union is to allow runtime dispatch based on the tag. However, 
 the process of choosing which function goes with which tag 
 takes place entirely at compile time.
Thanks. That makes sense.
May 09
prev sibling parent bachmeier <no spam.net> writes:
On Sunday, 6 May 2018 at 19:18:02 UTC, Paul Backus wrote:
 SumType is a generic sum type for modern D. It is meant as an 
 alternative to `std.variant.Algebraic`.
Someone posted a question about this on our subreddit: https://www.reddit.com/r/d_language/comments/8iz9hw/sumtype_03_sum_type_with_pattern_matching/
May 14