Live data from Hacker News

Applying “make invalid states unrepresentable”

kevinmahoney.co.uk

71–80 of 193 posts

Re: Applying “make invalid states unrepresentable”

#71
post #55

Earlier quoted context omitted.

Additionally, turning (startDate, endDate) into a set of dates will make the code more complex in some places. Before: SELECT event FROM events WHERE endDate After: Whatever additional complexity you add to your codebase to query end dates.

It's not that much more complex: if you do SELECT event FROM events WHERE startDate then all but one of the results (the one with the greatest `startDate`) will also have an implicit end-date prior to 2021.

Until business tells you that endDate is not necessarily greater than startDate. <- real world experience

Re: Applying “make invalid states unrepresentable”

#72
post #26

In general I agree that it's nice to make invalid states unrepresentable, but I'm not sure if I agree that this counts as a fundamental "invalid state". There is nothing about contracts which require that you can only have one active at the same time, or that that current one must be open ended. From a practical point of view it might be advantageous if you maintain only a single contract with a customer at all times…

I agree very much with your comment.

I've found the fundamental principle that helps to keep the system extensible is to: make your system model the real world accurately.

This involves building the system concepts closely mapped onto real world concepts without taking shortcuts.

That way when the requirements change, all the fundamental pieces of the system stay valid, and only the piece that is changing tends to need updating.

This helps to void the problem you mentioned of needing to re-design the full system, keeping the system extensible.

Re: Applying “make invalid states unrepresentable”

#73
post #52
post #43

Earlier quoted context omitted.

Then the code will be changed. Making up business requirements is the number one reason for instant legacy code. Code is not set in concrete, you can add that flexibility later when it is needed, but making everything overly generic to make it easier to "implement new requirements" only leads to code that is hard to change in my experience. Also don't forget that this is only an example.

The YAGNI (you aint gonna need it) principle overrides the DRY principle imo.

Yes - as does AHA (Avoid Hasty Abstractions). IMHO.

Re: Applying “make invalid states unrepresentable”

#74
post #53
post #26

In general I agree that it's nice to make invalid states unrepresentable, but I'm not sure if I agree that this counts as a fundamental "invalid state". There is nothing about contracts which require that you can only have one active at the same time, or that that current one must be open ended. From a practical point of view it might be advantageous if you maintain only a single contract with a customer at all times…

> Multiple times I've designed systems where I've reduced the representable states to the minimum, and when some requirements change I realize I have to re-design the full system. Yes, if requirements change, you change the design and code to support the new requirements. Compromising the consistency and maintainability of the current design to accommodate a hypothetical future requirement change is a bad trade-off I…

> Yes, if requirements change, you change the design and code to support the new requirements.

Code and representation (i.e. schema) are vastly different. In my experience it's takes an order of magnitude longer to change a representation than to change code. Once there are multiple services/tools which works with a representation you typically have to support both the new and the old representation at the same time (since you can't rollout everything simultaneously).

> Compromising the consistency and maintainability of the current design to accommodate a hypothetical future requirement change is a bad trade-off IMHO

Designing a representation which can handle possible requirement changes does not necessarily mean "compromising the consistency and maintainability". We have great tools for ensuring consistency (e.g. transactions and constraints in SQL databases), and I don't exactly see how this new representation is more "maintainable" than the old one (although we don't have all the information in this article).

Re: Applying “make invalid states unrepresentable”

#75
post #9
post #3

This is a good introduction on a conceptual level. I think a large contributor to the problem is story-oriented development, where all that matters in the sprint is "getting it done" and not looking at the broader context. To make unrepresentable states practical, Scott Wlaschin has an excellent write-up here (0). His book (plugged in that article) is also excellent. [0] https://fsharpforfunandprofit.com/posts/design…

> I think a large contributor to the problem is story-oriented development, where all that matters in the sprint is "getting it done" and not looking at the broader context. I think you have a point here. This design offers much better safety, comparable to "parsing instead of validating". But it requires up-front design. And that is indeed "verboten" in modern software development management style. Why is it "verbot…

+1, favorited.

Re: Applying “make invalid states unrepresentable”

#76
post #65

So Google's protocol buffers have this feature called "required" fields, which enforce schema in the type system. You should never use it. Never. It's one of those things that sound good until you're a few years into the project. Similar to how you should never be using meaningful IDs as primary keys for objects, always use meaningless fingerprint-like integers. Or how all integers should be signed unless you're dead…

I feel that this advice is almost opposite to that given in the article. By making all fields optional, your data model no longer helps in making invalid states unrepresentable.

Re: Applying “make invalid states unrepresentable”

#77

This is good article. But the second example seems to suffer from the defect of the first. Removing default contracts and representing fixed contracts as intervals leaves it possible that these fixed contracts can overlap....which is probably...undesirable? In that case, applying the remedy of the first example (a set of dates, and inferring that every 2nd (even zero length, to account for adjacent fixed) interval wi…

"It would be cool to see a list of, like, "Programming Heuristics", ranked by decreasing general applicability, of which this rule was a member somewhere far down the list."

+1 for this! Anyone got good links to share?

Re: Applying “make invalid states unrepresentable”

#78
post #27

While this is great if you know exactly what you want to achieve, it does “lock you in” those constraints on a more fundamental level. More times than I can count I’ve seen business requirements change to require those “unrepresentable” states, and since you’ve now designed you whole data model around it you need to add awful hacks to make it work. The timeline example is actually very telling. A lot of times you’d a…

You could always split your types into frontend and backend types where the backend ones are more open and the frontend ones are more restricted. I don't necessarily mean FE/BE as on the web. A lot of code is only interested in shuffling around data anyway, the shape is fairly uninteresting.

I would put it the other way around: make your basic representation restricted, but present a more permissive API. This way, the data model helps enforce your constraints, but you don't need to redesign the API when the requirements (inevitably) change.

Re: Applying “make invalid states unrepresentable”

#79
Another application of this principle is in data representation, and why I think text-based formats are horrible in general for communication between software that doesn't involve a human reading it the majority of the time: there, the "invalid states" not only cause complexity in the parser, but they also waste space (think of storing a 4-byte integer as the 4 bytes directly, vs. a string of variable-length ASCII text.)

Re: Applying “make invalid states unrepresentable”

#80
post #12

I appreciate what people are getting at with “make invalid states unrepresentable”, but it can't be the best description of what the true objective is. After all, the first language to make invalid states unrepresentable was probably TECO https://en.wikipedia.org/wiki/TECO_(text_editor)#As_a_progra... ...

Regarding "make invalid states unrepresentable", I'm curious what others think of FSM (Finite State Machines), eg use of XState (vs eg Redux) in the FE webapp state mgmt space.
Post reply on HN