Re: [rust-dev] RFC: conventions for default arguments

2013-05-30 Thread Daniel Micay
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

2013-05-30 Thread Mitch Skinner
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

2013-05-30 Thread Tommy M. McGuire
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

2013-05-30 Thread Patrick Walton

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

2013-05-30 Thread Tommy M. McGuire
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

2013-05-30 Thread Niko Matsakis
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

2013-05-30 Thread Daniel Micay
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

2013-05-30 Thread Niko Matsakis
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