3 ms·
It actually makes code a bit cleaner if data has boolean descriptors instead of enums for describing group or partial identity. Easier to check for thing.isSome
by eurasiantiger 4y ago
It actually makes code a bit cleaner if data has boolean descriptors instead of enums for describing group or partial identity. Easier to check for thing.isSomething than thing.group === someArbitraryValue. Just don’t allow them to enter illegal states or depend on other state. :)
- derefr 4y agoBut why not `thing.isSomething()` that's just a pure function defined as `return thing.state in STATES_THAT_ARE_SOMETHING`?
- eurasiantiger 4y agoHow do you store that in the database? That’s an ORM-level solution, which just hides/black-boxes the ugly code. Also, I already specified ”no illegal state”, which could just as well be ”no state”.
- derefr 4y ago> How do you store that in the database? 1. A very small dimension table, defining the set of flags in terms of the current state: (user_lifecycle_state, is_a, is_b, is_c, ...). Join it to the fact table when you need it. 2. Computed columns in a writable view wrapping the table. 3. Procedures/functions that take the lifecycle state as input, so you can `SELECT u.id, ..., is_active(u.lifecycle_state) AS is_active FROM users`. > which just hides/black-boxes the ugly code I don't see what's ugly about it. The point of defining something as a FSM is that that's a formal definition on the design level, separate from any particular implementation; you can write a single stateless module that defines these predicates in terms of the lifecycle-states on any or all layers of the stack they're needed, and they'll all work the same, because they're all working off a formal definition of the meaning of each state. Compare and contrast: Postgres has an `inet` type for IP addresses. It has a function `family(inet)`, which returns 4 or 6. Your business layer's runtime probably also has a function like that somewhere. They won't necessarily have the same outputs (i.e. your business layer's version might be a pair of predicates `is_ipv4?` and `is_ipv6?`) — but they'll both answer the same way semantically given the same inputs, because they're both working off of a shared formal definition of what an IP address is.
- eurasiantiger 4y agoThanks for the clarification. The example, however, doesn’t fit reality particularly well given how few implementations actually agree on all possible forms of v4 and v6 addresses.
- tempodox 4y agoThen write a predicate function that wraps this comparison. Extra points if you use a language that can inline the predicate, so you don't have to make a subroutine call for that.