1. 10
  1.  

  2. 6

    Not mentioned and IMO important is that adding Default to the struct M means users would be able to create an M directly, without going through the constructor function M::up(). Furthermore, backwards compatibility would imply that the Default trait implementation can’t be removed in the future.

    If the goal is only to reduce typing, then I think a standalone fn default<'a>() -> M<'a> function would work just as well. That would be usable in a struct literal in the same module, and wouldn’t expand the API contract.

    1. 2

      That’s a great point, I did not think of that.

      1.  

        a standalone fn default<’a>() -> M<’a> function would work just as well.

        Except for #[derive(Default)] for struct that contains fields of this type.

      2. 2

        You’ve given up the ability to have the compiler take you through all those initialisation points, and you risk missing the places where you do want to add something different from the “default”.

        Besides, what does “default” mean, anyway? It’s often neutral “with respect to some other operation”, in which case the abstraction you’re reaching for is “monoid”.