[rust-dev] RFC: conventions for default arguments

Niko Matsakis niko at alum.mit.edu
Thu May 30 02:56:37 PDT 2013

I have a proposal about library conventions and I'm not sure where is
the right place to pose it. I think that anytime there is a "default"
argument of generic type that may or may not get used, we should offer
two variants, one of which requires the Zero trait, and one of which
takes a closure. This follows precedent from many languages, including
Smalltalk, Scala, and to some extent Haskell, since in Haskell all
evaluation is lazy.

Right now, we typically either (1) only offer a version that takes
the default "by value", as with `option::get_or_default`:

    fn get_or_default(self, def: T) -> T;

But I often find in practice I cannot use this because it always
evaluates `def`. Even something as simple as:

    let vec = opt_vec.get_or_default(~[]);

allocates unconditionally. I would prefer:

    fn get_or_default(self: def: &fn() -> T) -> T;

The only case where I think this pattern is really useful is
something like:

    let is_true = opt_bool.get_or_default(false);
    let count = opt_counter.get_or_default(0);

Under my proposal, we would have:

    fn get_or_default(self, def: &fn() -> T) -> T;
    fn get_or_zero(self) -> T; // where T:Zero

Then you could write:

    let vec = opt_vec.get_or_default(|| ~[]);
    let is_true = opt_bool.get_or_zero();
    let count = opt_counter.get_or_zero();

At worst, if the Zero default isn't what you want,
you might to write something like:

    let foo = opt_bool.get_or_default(|| true); 

But I think our closure syntax is lightweight enough that this
is not a big deal.

Another example is in Hashmaps, where we offer two variants on the
"find-or-insert" pattern:

    fn find_or_insert(&mut self, K, V) -> Option<&V>
    fn find_or_insert_with(&mut self, K, &fn(&K) -> V) -> Option<&V>

Under my proposal there would just be:

    fn find_or_insert(&mut self, K, &fn(&K) -> V) -> Option<&mut V>
    fn find_or_insert_zero(&mut self, K) -> Option<&mut V> // where V:Zero



More information about the Rust-dev mailing list