Re: [rust-dev] RFC: conventions for default arguments
On Thu, May 30, 2013 at 4:49 PM, Mitch Skinner wrote: > I'm not sure how much this overlaps with what you're proposing, but > regarding hashmaps: > > I'm hoping to see overloadable IndexAddAssign and IndexMulAssign and friends > someday, and the notion of neutral element differs between them, e.g.: > > > impl HashMap { > ... IndexAddAssign ... > } > impl HashMap { > ... IndexMulAssign ... > } > > So I guess the question I'm asking is, is Zero universal enough to make it a > library convention? > > Mitch I don't think Zero/One are needed for Index methods, since it's already defined as failing if the element isn't present for vectors. It would be odd to implement it differently for other types. ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] RFC: conventions for default arguments
I'm not sure how much this overlaps with what you're proposing, but regarding hashmaps: I'm hoping to see overloadable IndexAddAssign and IndexMulAssign and friends someday, and the notion of neutral element differs between them, e.g.: impl HashMap { ... IndexAddAssign ... } impl HashMap { ... IndexMulAssign ... } So I guess the question I'm asking is, is Zero universal enough to make it a library convention? Mitch On Thu, May 30, 2013 at 2:56 AM, Niko Matsakis wrote: > 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 > ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] RFC: conventions for default arguments
On 05/30/2013 10:44 AM, Patrick Walton wrote: > You can add additional bounds to type arguments for a subset of the > methods. Use a different impl block: Cool! I didn't realize that. -- Tommy M. McGuire mcgu...@crsr.net ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] RFC: conventions for default arguments
On 5/30/13 8:40 AM, Tommy M. McGuire wrote: On 05/30/2013 04:56 AM, Niko Matsakis wrote: 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? I like the idea of the closure, but (as a relative newcomer), how would the Zero trait be specified? Wouldn't it require all HashMap's V's implement Zero? You can add additional bounds to type arguments for a subset of the methods. Use a different impl block: impl HashMap { ... find_or_insert goes here ... } impl HashMap { ... find_or_insert_zero goes here ... } Patrick ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] RFC: conventions for default arguments
On 05/30/2013 04:56 AM, Niko Matsakis wrote: > 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? I like the idea of the closure, but (as a relative newcomer), how would the Zero trait be specified? Wouldn't it require all HashMap's V's implement Zero? -- Tommy M. McGuire mcgu...@crsr.net ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] RFC: conventions for default arguments
On Thu, May 30, 2013 at 08:14:39AM -0400, Daniel Micay wrote: > 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. That's fine too, though I kind of thought this is what Zero was. Still, a `Default` trait that defines `new()` seems clearer and less math-geeky than using `Zero`. I'm fine with either. Mainly I just don't want to take random default values that may or may not be used, since that's only convenient if the type happens to be a scalar, basically. Niko ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] RFC: conventions for default arguments
On Thu, May 30, 2013 at 5:56 AM, Niko Matsakis 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
[rust-dev] RFC: conventions for default arguments
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 ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev