One thing that’s cool about this that’s not mentioned in the post: this Connection type is zero-sized, aka, has no data. So it will be fully optimized away; it never really existed, other than to make this type safe.
Here’s a little iteration on that idea: Rusts Into and From let you define the transitions in a generic fashion. This allows you to create methods that take values that can move towards a certain state (or are already in the desired state).
Note though that From and Into are only usable for conversions that cannot fail, but similar patterns that return Result are possible.
This is a good idea - I haven’t thought of using the standard traits for these transitions. I’ll definitely write a follow-up.
A different example is needed though - as you said, From isn’t allowed to fail (but there’s unstable TryFrom). Plus we can’t pass any parameters either. So the uses are a bit more limited. I’ll think about this some more and discuss it in a follow-up.
Yeah, it’s obviously more complex then that. Also, this assumes that transition between states is instantaneous. Probably, you want Disconnected, Connected and Connecting where Connecting probably has future/promise-like properties.
Parameters can probably be solved by having a mix of both styles: Call a method to get a promise on a future state. Accept those promises as parameters.
I think the example is really interesting.
god i love this so much. better programming through types.
I think there’s a typo: y.connect() should be x.connect().
Are there any downsides to this approach, esp. from a UX perspective? I’ve encountered phantom types in Haskell and they’re cool for demarcating regions with effects, but I haven’t seen them used like this.
It’s a bit more complicated to implement, and the types in general just get more complex.
That is pretty neat. Thanks.