Nice post, Timo!
The only problem I have with this pattern is persistence. Let me elaborate.
Your example is synchronous. But imagine that every step of it is async and might take days to finish. So every step of the process should be persistable. And that is not a problem, the problem is how to get that object back since you don’t know which type of object is save to db you can’t know what kind of object will be restored back which means there is no way to write a single method to get it from storage. In short: while working with object is pretty nice, safe and straightforward it’s almost impossible to work with it when it should be saved to db.
Am I missing something here?
Hi Arthur, glad you liked it!
That’s in fact the first example I could think of where the pattern has obvious drawbacks.
I wrote a longer response to a similar question in the reddit comments here: https://www.reddit.com/r/rust/comments/m7nox4/the_case_for_the_typestate_pattern_the_typestate/grf0sle/?utm_source=reddit&utm_medium=web2x&context=3
So no, I don’t think you’re missing something here.
I think there are ways to have these kinds of serialization requirements and still use the typestate pattern, but it becomes a lot less attractive.
But if the state transitions are extremely subtle and making the input and output states visible in the type signatures helps a lot with correctness and readability, it might still be worth it.