Pre-pre-RFC: syntactic sugar for `Default::default()`

First of all, thank you @ekuber for putting the work into this RFC-to-be. I definitely think that the ergonomics around Default::default() can and should be improved.

I'm not so sure about the addition of a magic syntax though, instead of addressing some fundamental problems with the way that the ..Default::default() "operator" works.

(I also haven't read all comments on this, some of which seemed to be going in a very different direction from the actual RFC?)

In short: I think adding a new syntax sugar for nested Default invocations would feel inconsistent, if for example nested match defaults ( _ => ... ) are not similarly handled. Especially because ..Default::default() is quite recognisable, whereas ..* is really not. I also don't think that just shortening the function name is really going to be a big quality of life improvement. There might be some more possible one-liners, but in the grand scheme of things it doesn't really change anything.

Instead, I think ergonomic improvements around Default should attack the root of the problem, namely that partial default implementations need to be possible.

At least from interacting with other projects, and the projects I work on, the issue is usually having to repeat a lot of fields that should be default-able.

For example:

struct Config {
  path: PathBuf
  strict_mode: bool,
  version: u8
}

The problem with implementing a Default for this struct is that path will end up having to be an invalid value, and we have to hope that it is instantiated correctly by overriding the field with a better value (i.e. Config { path, ..Default::default() }). If we allow for partial Default implementations, there could be default values for strict_mode and version, but the type system will enforce giving path a concrete value before it is a valid struct.

Without special language support this could be implemented with a derive macro that generates a new struct where all fields are Option<T>, and a transformation from this temporary struct to the real struct, where a builder takes the set of inputs that is required to make it a complete struct.

With some language support this could potentially be much easier to use, and an elegant solution to avoid having stale fields provided by wrong (or incomplete) Default values on a struct.

This suggestion is a bit off what the original RFC-to-be proposes, but I think it's a much better solution to the underlying problem of what makes using Default so cumbersome.

Now, this wouldn't really make 5-nested structs where each has a default any less cumbersome, but I think it might encourage people to write their structs and builders in a way that makes it easier to not end up in these situations.

6 Likes