Need Advice: Union or Variant?

Petar Petar
Thu Nov 17 21:19:56 UTC 2022


On Thursday, 17 November 2022 at 20:54:46 UTC, jwatson-CO-edu 
wrote:
> I have an implementation of the "[Little 
> Scheme](https://mitpress.mit.edu/9780262560993/the-little-schemer/)" educational programming language written in D, [here](https://github.com/jwatson-CO-edu/SPARROW)".
>
> It has many problems, but the one I want to solve first is the 
> size of the "atoms" (units of data).
>
> `Atom` is a struct that has fields for every possible type of 
> data that the language supports. This means that a bool `Atom` 
> unnecessarily takes up space in memory with fields for number, 
> string, structure, etc.
>
> Here is the 
> [definition](https://github.com/jwatson-CO-edu/SPARROW/blob/main/lil_schemer.d#L55):
>
> ```d
> enum F_Type{
>     CONS, // Cons pair
>     STRN, // String/Symbol
>     NMBR, // Number
>     EROR, // Error object
>     BOOL, // Boolean value
>     FUNC, // Function
> }
>
> struct Atom{
>     F_Type  kind; // ---------------- What kind of atom this is
>     Atom*   car; // ----------------- Left  `Atom` Pointer
>     Atom*   cdr; // ----------------- Right `Atom` Pointer
>     double  num; // ----------------- Number value
>     string  str; // ----------------- String value, D-string 
> underlies
>     bool    bul; // ----------------- Boolean value
>     F_Error err = F_Error.NOVALUE; // Error code
> }
>
> ```
> Question:
> **Where do I begin my consolidation of space within `Atom`?  Do 
> I use unions or variants?**

In general, I recommend 
[`std.sumtype`](https://dlang.org/phobos/std_sumtype), as it is 
one of the best D libraries for this purpose. It is implemented 
as a struct containing two fields: the `kind` and a `union` of 
all the possible types.
That said, one difficulty you are likely to face is with 
refactoring your code to use the 
[`match`](https://dlang.org/phobos/std_sumtype#.match) and 
[`tryMatch`](https://dlang.org/phobos/std_sumtype#.tryMatch) 
functions, as `std.sumtype.SumType` does not expose the 
underlying kind field.

Other notable alternatives are:
* [`mir-core`](https://code.dlang.org/packages/mir-core)'s 
`mir.algebraic`: http://mir-core.libmir.org/mir_algebraic.html
* 
[`taggedalgebraic`](https://code.dlang.org/packages/taggedalgebraic): https://vibed.org/api/taggedalgebraic.taggedalgebraic/


More information about the Digitalmars-d-learn mailing list