Live data from Hacker News

Applying “make invalid states unrepresentable”

kevinmahoney.co.uk

41–50 of 193 posts

Re: Applying “make invalid states unrepresentable”

#41
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…

That could be fixed with 1 additional concept. Instead of

    Customer: 1 - 1: Set(Dates)
What if it was

    Customer 1 - *: Contract: 1 - 1: Set(Dates)
Overlap achieved.

Re: Applying “make invalid states unrepresentable”

#42
This is part of approach to programming that is more popular in functional world.

You take requirements and make system exactly right to fit these requirements perfectly and don't bother with any other concerns.

When you design this close to the requirements you get better, faster and more elegant code that's easier to understand - but when requirements change you have to do much more work to adapt. Suddenly a state which was previously invalid is valid, or a part of system that only needed one kind of input needs 4 different inputs from separate parts of your code. Have fun basically rewriting your program.

That's IMHO the main motivation between differences in functional and OO programming - how close to the requirements you want to design your code.

Re: Applying “make invalid states unrepresentable”

#43
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…

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.

Re: Applying “make invalid states unrepresentable”

#45
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.

Re: Applying “make invalid states unrepresentable”

#46
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…

There are trade-offs, of course, but I'm generally not a fan of using implicit defaults for business applications (i.e., the application infers the default when there's no data).

If things go well, business data outlives business applications. After years or decades, it can be a major pain to figure out all the "secret" values that aren't actually in the data.

Re: Applying “make invalid states unrepresentable”

#47
post #11
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 that's exactly backwards. This kind of overcomplicated representation usually happens because people put too much effort into designing their representations up front. If you follow story-oriented development and only implement the parts…

I assure you that I have wasted enough time fixing story-oriented development with major refactorings, because some edge cases weren't possible to be easily extended in the existing code.

Also have experience fixing story-oriented development with dirty workarounds, because major refactorings were also required, but not desired by whom was paying for the stories.

Both ways I didn't care, it was money on the bank anyway.

Re: Applying “make invalid states unrepresentable”

#48
post #42

This is part of approach to programming that is more popular in functional world. You take requirements and make system exactly right to fit these requirements perfectly and don't bother with any other concerns. When you design this close to the requirements you get better, faster and more elegant code that's easier to understand - but when requirements change you have to do much more work to adapt. Suddenly a state…

This kind of approach (type driven development) was already popular in Algol derived languages, hence why the cowboy coder would call us on Ada, Modula-2, Object Pascal side of the fence, programming with straitjacket.

Re: Applying “make invalid states unrepresentable”

#49
I like the concept but I’ve seen a fair few examples of where the developers and users clearly had differing opinions about which states are invalid!

Dates are a rich vein of examples. Some users will happily consider “25th December” to be a date, without any year, because it might be the name of a folder in which they store their Christmas stuff. More seriously, genealogists or historians may want to record “25th December” (again without a year) as the date of a photograph because they can clearly see it was taken on a Christmas, they just don’t know which one. The naive developer would just slap a DateTime type onto the system and feel good about having avoided malformed input.

Re: Applying “make invalid states unrepresentable”

#50
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 will be default,) introduces another bug where if you lop off any random date in that set or list, you invert everything.

I love the concept represented here, it is akin to normalization as in...simplify the representation so no redundancy is introduced as this usually leads to better results...but it seems it's no guarantee of better results.

But maybe that's just because the "model" we are simplifying from was not an optimal representation. Perhaps there's a better model of the second example that doesn't end up with the defect of the first example.

I really like this article but am struck by how something that I wanted to be almost a silver bullet trick for modeling, ends up being a mass of compromises mired in tradeoffs that doesn't show any clear way forward in the general case. Still, probably a good rule of thumb, but I guess this rule is not optimal...as it can have so many unworkable misinterpretations/misapplications.

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.

Post reply on HN