Representing Heterogeneous Data
journal.stuffwithstuff.com
journal.stuffwithstuff.com
Interesting post! Nim uses variant/case objects as well. Generally they're pretty handy and more flexible than sum types as you can access non-variant fields as regular objects. Though it means you can't use the same field name twice, however on the other hand you can bring common fields out of the case portion. Also, a single object can have multiple case variants which can be handy.
There's a PR for adding the stricter sum types and pattern matching as well. https://github.com/nim-lang/RFCs/issues/525 Currently I just use a library for sum type syntax on top of object variants: https://github.com/andreaferretti/patty
We don’t have one melee fighter, but usually multiple, so design for that case. Normalize your data (split data that’s optional into own types) and have multiple tables/arrays for each of these components. Then create another table for the possible combinations, e.g. a melee fighter table. You then iterate over the melee fighter table with your melee code rather than the component tables
In games, things often transform into other things, and we want to still consider them the same entity.
1. Objects say you are a melee fighter, and a melee fighter is defined as having X, Y, Z
2. Databases instead say you exist, and if you have X, Y, Z then you can be called a melee fighter.
Thus to transform an entity from one type to another (melee fighter to ranged fighter), you simply need to remove the properties associated with melee fighter and add the properties associated with ranged fighter — and the fact that it is one or another is derived from whatever property it is left with.
And then of course to say someone is both a melee and ranged fighter, then you just need to add the properties of both — being A vs B is not by definition, it’s derived from the properties you have
A rock can be viewed as a chair if it meets sufficient parameters for sitting; it can be viewed as a weapon just the same. These aren’t inherent to the act of being a rock, but rather derived from the composition of the rock
The result of a database query may have an immutable type, but it can also become stale, like an invalid cache entry. That's a possible bug. Perhaps there's some trick that would allow us to treat a live object as unchanging, with a fixed type and shape, but only within a limited scope in which we can prove it won't mutate?
For example, in a single-threaded language, it seems like we should be able to do a runtime check to get a more specific type and use it until the next await. The runtime check only needs to be done once in that scope.
Each of your things that you want to identify and tell apart from other has an ID. Nothing else like a type is required.
Your ID can be registered in the melee fighter “system” (ECS lingo), inserted into the melee fighter table (relational db lingo). But it can also be registered in the table for ghosts, resulting in little girls reacting by crying, running away and shouting for a guard.
Once the ghost melee fighter finishes a quest to regain his body he’s removed from the ghost table. The advantage here is that this scales really well due the melee fighter and ghost systems not being tied to each other. In OOP you get combinatorial explosions of types resulting in a “god object” with many booleans to turn behavior off, or switching from type hierarchies to composition.
With both you kinda separate your application into a control-plane (functions and other code) and a data-plane (in-memory database). With the control-plane referencing entities from the data-plane via opaque identifiers.
Conjunctive queries over the database are then equivalent to a structural type system with literal types, and allow for accepting potentially every entity in the system at every point in the system so long as the types match.
TBH I would probably take a look at terminusDB though. They do things a bit differently, and are def. more opinionated (more closed world, more databasey) but that opinionatedness helps provide a bit saner/stable foundation than the very grown rest of the ecosystem imho.