On Thu, May 30, 2013 at 5:56 AM, Niko Matsakis <n...@alum.mit.edu> wrote:
> 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
>
> Thoughts?
>
>
> Niko

We could have a more generic trait than `Zero` for this. For example,
Haskell has a third party data-default package[1] that's fairly widely
used (pandoc is one of the users) and there's a similar concept in C++
with default constructors. We could just standardize the
parameter-free `new` method this way.

[1] http://hackage.haskell.org/package/data-default-0.5.3
_______________________________________________
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to