Hacker News new | past | comments | ask | show | jobs | submit login
Representing Heterogeneous Data (stuffwithstuff.com)
59 points by grep_it 8 months ago | hide | past | favorite | 14 comments



> This is a real trade-off. The feature I have here provides strictly less static safety than using sum types. There is a slight performance cost to checking the type tag when accessing case-specific fields. In return, you get simpler, more familiar syntax for working with case-specific fields, including mutable ones.

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


For what it's worth, the representation the author chose to go with is almost verbatim identical to how you declare variant object types in Nim.


A bit surprising that this shows up here even though Bob apparently hasn’t figured out a good answer yet. Maybe someone will know a good solution?


The relational db/DOD/ECS solution would be to just not force things into a single type.

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


This. ECS is an extremely powerful approach that makes adding new features ridiculously easy but it does require somewhat of a conceptual readjustment at first from the usual "a class to rule them all" approach.


How about if the melee fighter switches weapons to a bow and arrow?

In games, things often transform into other things, and we want to still consider them the same entity.


I like to view it as:

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


This works, but the result of the query (starting from an object id) varies. What can a static type system do under these circumstances? It seems like it might as well be a dynamic field access?

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.


ECS is popular in games because each of your “things” can freely and dynamically change into anything. In a static type hierarchy this is not possible.

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.


If I'm understanding your question correctly (how do I change some of the components of the entity and still know it's the same entity) the answer is that usually in ECS entities have an ID assigned to them, so as long as the entity ID is the same it doesn't matter if the associated WeaponComponent records change.


I feel like RDF/TripleStores and ECS both offer nice solutions to this problem.

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.


Anyone know of any good books about or introductions to RDF triples that cover practical applications? I’ve been meaning to look into it for representing data about US laws and regulations but ChatGPT isn’t really helping.


"Semantic web for the working ontologist" by Dean Allemang and James Hendler might be a good starter if you want to go proper Rdf/RDFS/OWL.

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.


I'd also be really interested in something like this.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: