fat struct style guide?

monkyyy crazymonkyyy at gmail.com
Tue Feb 24 20:33:49 UTC 2026


On Tuesday, 24 February 2026 at 19:48:07 UTC, Julian Fondren 
wrote:
> On Tuesday, 24 February 2026 at 16:56:57 UTC, monkyyy wrote:
>> Its c-like code and enabling "unsafe" void* hacks.
>>
>> Gist code from last night(I already see one improvement and 
>> expect more):
>>
>> ```d
>> #!opend test app
>> import std;
>> import core.stdc.stdlib;
>> import core.sys.posix.dlfcn;
>>
>> enum animalid{cow=7,chicken,horse};
>>
>> struct animal{
>>     animalid id;
>>     string say;
>>     int age;
>> }
>> ...
>> ```
>
> An algebraic datatype, a sumtype, a discriminated union, etc. 
> And a 'fat pointer' is a just pointer to tagged data with some 
> Data-Oriented Design implications about the data. Wikipedia has 
> one good line about it:
>

Its an *intrusive* sumtype, fatpointers have different tradeoffs. 
Also see me asking for help with intrusive lists.

>> A tagged union can be seen as the simplest kind of 
>> self-describing data format. The tag of the tagged union can 
>> be seen as the simplest kind of metadata.
>
> With std.sumtype a 1:1 version of your code is a real pain, but 
> your method would be more painful if the variants weren't so 
> similar.

They are fat structs because you could have like 100 members. 
There are ~3 details that I think can matter for overloading, 
layout, different behavior, size.

Fat structs are making tradeoffs for layout similarity and I 
expect dividends on the subject.

> std.sumtype's also less painful over time, refusing 
> newanimal("idk"), having a compile-time exhaustiveness check. 
> There are some rough edges like .each! not working here.

Compile time exhaustiveness is a major tradeoff, even for 
correctness focused code.

```d
struct foo{
   string me;
   bar* left;
   bar* right;
}
alias bar=SumType!(null,int,float,bool,foo);
```

The recursion is hard to resolve; not impossible and I could 
suggest 3 ideas, but still, this doesn't work with the 3 sumtypes 
phoboes shipped.(1 of them was unjustifiably bad at this)

> Skipping "do",

`Do` is the main point here, if you call `dlsym` your half way to 
hotreloading. That sort of demo doesnt work well with a gist tho.

> int age(Animal a) => a.match!(
>     (Cow a) => a.age,
>     (Chicken a) => a.age,
>     (Horse a) => a.age,
> );

This is painful and would disqualify it if it was required, while 
snar didnt get an `apply!(a=>a.age)` into phoboes it should be 
entirely possible, I may have it somewhere, theres probably a 
supported 2 line solution as well. My sumtype gists would be able 
to implement it trivially.

> unittest {
> }
> ```

You also skipped "makechicken" and the effect that had on "say"

Its fun is a chicken says moo because it was raised a cow; 
videogame logic, why not.


More information about the Digitalmars-d-learn mailing list