1. 27
  1. 7

    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.

    1. 5

      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).

      https://is.gd/Lbzelm

      Note though that From and Into are only usable for conversions that cannot fail, but similar patterns that return Result are possible.

      1. 2

        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.

        1. 2

          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.

      2. 1

        I think there’s a typo: y.connect() should be x.connect().

        1. 1

          Thanks, fixed!

        2. 1

          That is pretty neat. Thanks.

          1. 1

            god i love this so much. better programming through types.

            1. 1

              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.

              1. 3

                It’s a bit more complicated to implement, and the types in general just get more complex.