Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2014-01-07 Thread Nick Cameron
I agree with Simon that doubling the API is inelegant. I think the solution
is adding sugar to make working with Option/Result easier -
(semi-)independent of the foo/foo_opt issue, I find working with Option
pretty painful.

I prefer the Haskell do sugar to refutable patterns in let. Similar in
spirit is the ? operator from Groovy, which I think is elegant and simple,
it is an alternative to the . operator for field access/method call. In
Rust it would have the following type and semantics:

\Gamma e : OptionT'
fType(T', f) = T

\Gamma e?f : OptionT

e?f ~~ match e { Somee = Somee.f, None = None }

and similarly for method call.

The ? operator has the same advantages and disadvantages as Haskell's do,
but is more concise.

Just another alternative to consider.


On Sat, Dec 7, 2013 at 9:41 AM, Simon Sapin simon.sa...@exyr.org wrote:

 We have some functions and methods such as [std::str::from_utf8](http://
 static.rust-lang.org/doc/master/std/str/fn.from_utf8.html) that may
 succeed and give a result, or fail when the input is invalid.

 1. Sometimes we assume the input is valid and don’t want to deal with the
 error case. Task failure works nicely.

 2. Sometimes we do want to do something different on invalid input, so
 returning an `OptionT` works best.

 And so we end up with both `from_utf8` and `from_utf8`. This particular
 case is worse because we also have `from_utf8_owned` and
 `from_utf8_owned_opt`, to cover everything.

 Multiplying names like this is just not good design. I’d like to reduce
 this pattern.

 Getting behavior 1. when you have 2. is easy: just call `.unwrap()` on the
 Option. I think we should rename every `foo_opt()` function or method to
 just `foo`, remove the old `foo()` behavior, and tell people (through
 documentation) to use `foo().unwrap()` if they want it back?

 The downsides are that unwrap is more verbose and gives less helpful error
 messages on task failure. But I think it’s worth it.

 What do you think?

 (PS: I’m guilty of making this worse in #10828, but I’d like to discuss
 this before sending pull requests with invasive API changes.)

 --
 Simon Sapin
 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev

___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2014-01-07 Thread Vadim
I can see how '?.' would work when foo() returns a struct, but what about
non-struct types, e.g. Optioni32 ?   Also, you'd still have to deal with
'None' at the end of the chain.   I think in most cases I'd rather have it
fail.

I also don't really like refutable let-patterns proposal, because stuff
like let Some(x) = foo(); does not work with chaining when foo() returns
a struct (and is still pretty wordy).

Maybe we need an operator for getting wrapped value?   This would be
similar to deref for [smart]pointers, except I think it should be a
postfix operator to allow for easy chaining.   Let's say we chose '^' for
this purpose, and implemented its' trait for Option, Result, etc.  Then one
could write:
let x = foo()^;
or
let y = foo()^.field;

Vadim



On Tue, Jan 7, 2014 at 11:30 AM, Nick Cameron li...@ncameron.org wrote:

 I agree with Simon that doubling the API is inelegant. I think the
 solution is adding sugar to make working with Option/Result easier -
 (semi-)independent of the foo/foo_opt issue, I find working with Option
 pretty painful.

 I prefer the Haskell do sugar to refutable patterns in let. Similar in
 spirit is the ? operator from Groovy, which I think is elegant and simple,
 it is an alternative to the . operator for field access/method call. In
 Rust it would have the following type and semantics:

 \Gamma e : OptionT'
 fType(T', f) = T
 
 \Gamma e?f : OptionT

 e?f ~~ match e { Somee = Somee.f, None = None }

 and similarly for method call.

 The ? operator has the same advantages and disadvantages as Haskell's do,
 but is more concise.

 Just another alternative to consider.


 On Sat, Dec 7, 2013 at 9:41 AM, Simon Sapin simon.sa...@exyr.org wrote:

 We have some functions and methods such as [std::str::from_utf8](http://
 static.rust-lang.org/doc/master/std/str/fn.from_utf8.html) that may
 succeed and give a result, or fail when the input is invalid.

 1. Sometimes we assume the input is valid and don’t want to deal with the
 error case. Task failure works nicely.

 2. Sometimes we do want to do something different on invalid input, so
 returning an `OptionT` works best.

 And so we end up with both `from_utf8` and `from_utf8`. This particular
 case is worse because we also have `from_utf8_owned` and
 `from_utf8_owned_opt`, to cover everything.

 Multiplying names like this is just not good design. I’d like to reduce
 this pattern.

 Getting behavior 1. when you have 2. is easy: just call `.unwrap()` on
 the Option. I think we should rename every `foo_opt()` function or method
 to just `foo`, remove the old `foo()` behavior, and tell people (through
 documentation) to use `foo().unwrap()` if they want it back?

 The downsides are that unwrap is more verbose and gives less helpful
 error messages on task failure. But I think it’s worth it.

 What do you think?

 (PS: I’m guilty of making this worse in #10828, but I’d like to discuss
 this before sending pull requests with invasive API changes.)

 --
 Simon Sapin
 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev



 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev


___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2014-01-07 Thread Nick Cameron
I think that you eventually have to deal with the Some or None-ness of an
expression is an advantage of the ? operator, it means you can't ignore
failure, but you don't have to deal with it at every step of a compound
expression. Using an operator for unwrap has the same disadvantage as plain
unwrap - it lets you ignore the failure case.


On Wed, Jan 8, 2014 at 1:42 PM, Vadim vadi...@gmail.com wrote:

 I can see how '?.' would work when foo() returns a struct, but what about
 non-struct types, e.g. Optioni32 ?   Also, you'd still have to deal with
 'None' at the end of the chain.   I think in most cases I'd rather have it
 fail.

 I also don't really like refutable let-patterns proposal, because stuff
 like let Some(x) = foo(); does not work with chaining when foo() returns
 a struct (and is still pretty wordy).

 Maybe we need an operator for getting wrapped value?   This would be
 similar to deref for [smart]pointers, except I think it should be a
 postfix operator to allow for easy chaining.   Let's say we chose '^' for
 this purpose, and implemented its' trait for Option, Result, etc.  Then one
 could write:
 let x = foo()^;
 or
 let y = foo()^.field;

 Vadim



 On Tue, Jan 7, 2014 at 11:30 AM, Nick Cameron li...@ncameron.org wrote:

 I agree with Simon that doubling the API is inelegant. I think the
 solution is adding sugar to make working with Option/Result easier -
 (semi-)independent of the foo/foo_opt issue, I find working with Option
 pretty painful.

 I prefer the Haskell do sugar to refutable patterns in let. Similar in
 spirit is the ? operator from Groovy, which I think is elegant and simple,
 it is an alternative to the . operator for field access/method call. In
 Rust it would have the following type and semantics:

 \Gamma e : OptionT'
 fType(T', f) = T
 
 \Gamma e?f : OptionT

 e?f ~~ match e { Somee = Somee.f, None = None }

 and similarly for method call.

 The ? operator has the same advantages and disadvantages as Haskell's do,
 but is more concise.

 Just another alternative to consider.


 On Sat, Dec 7, 2013 at 9:41 AM, Simon Sapin simon.sa...@exyr.org wrote:

 We have some functions and methods such as [std::str::from_utf8](http://
 static.rust-lang.org/doc/master/std/str/fn.from_utf8.html) that may
 succeed and give a result, or fail when the input is invalid.

 1. Sometimes we assume the input is valid and don’t want to deal with
 the error case. Task failure works nicely.

 2. Sometimes we do want to do something different on invalid input, so
 returning an `OptionT` works best.

 And so we end up with both `from_utf8` and `from_utf8`. This particular
 case is worse because we also have `from_utf8_owned` and
 `from_utf8_owned_opt`, to cover everything.

 Multiplying names like this is just not good design. I’d like to reduce
 this pattern.

 Getting behavior 1. when you have 2. is easy: just call `.unwrap()` on
 the Option. I think we should rename every `foo_opt()` function or method
 to just `foo`, remove the old `foo()` behavior, and tell people (through
 documentation) to use `foo().unwrap()` if they want it back?

 The downsides are that unwrap is more verbose and gives less helpful
 error messages on task failure. But I think it’s worth it.

 What do you think?

 (PS: I’m guilty of making this worse in #10828, but I’d like to discuss
 this before sending pull requests with invasive API changes.)

 --
 Simon Sapin
 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev



 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev



___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2014-01-07 Thread Vadim
On Tue, Jan 7, 2014 at 6:39 PM, Nick Cameron li...@ncameron.org wrote:

 I think that you eventually have to deal with the Some or None-ness of an
 expression is an advantage of the ? operator, it means you can't ignore
 failure, but you don't have to deal with it at every step of a compound
 expression. Using an operator for unwrap has the same disadvantage as plain
 unwrap - it lets you ignore the failure case.


First of all, it does not let me ignore errors - if I try to unwrap() a
None, it will kill my program (or at least the current task).   Whether
this is what I want, depends on the use case.   In my experience, more
often than not, an error returned by an API represents a bug in the
program.  So what am I gonna do when I see that something has error'ed
out?  I will probably just call fail!().

Anyways, I think this thread was about how to avoid having both foo() and
foo_opt() versions of every API, and many people (including myself),
consider unwrap() too noisy.  So...

Vadim




 On Wed, Jan 8, 2014 at 1:42 PM, Vadim vadi...@gmail.com wrote:

 I can see how '?.' would work when foo() returns a struct, but what about
 non-struct types, e.g. Optioni32 ?   Also, you'd still have to deal with
 'None' at the end of the chain.   I think in most cases I'd rather have it
 fail.

 I also don't really like refutable let-patterns proposal, because stuff
 like let Some(x) = foo(); does not work with chaining when foo() returns
 a struct (and is still pretty wordy).

 Maybe we need an operator for getting wrapped value?   This would be
 similar to deref for [smart]pointers, except I think it should be a
 postfix operator to allow for easy chaining.   Let's say we chose '^' for
 this purpose, and implemented its' trait for Option, Result, etc.  Then one
 could write:
 let x = foo()^;
 or
 let y = foo()^.field;

 Vadim



 On Tue, Jan 7, 2014 at 11:30 AM, Nick Cameron li...@ncameron.org wrote:

 I agree with Simon that doubling the API is inelegant. I think the
 solution is adding sugar to make working with Option/Result easier -
 (semi-)independent of the foo/foo_opt issue, I find working with Option
 pretty painful.

 I prefer the Haskell do sugar to refutable patterns in let. Similar in
 spirit is the ? operator from Groovy, which I think is elegant and simple,
 it is an alternative to the . operator for field access/method call. In
 Rust it would have the following type and semantics:

 \Gamma e : OptionT'
 fType(T', f) = T
 
 \Gamma e?f : OptionT

 e?f ~~ match e { Somee = Somee.f, None = None }

 and similarly for method call.

 The ? operator has the same advantages and disadvantages as Haskell's
 do, but is more concise.

 Just another alternative to consider.


 On Sat, Dec 7, 2013 at 9:41 AM, Simon Sapin simon.sa...@exyr.orgwrote:

 We have some functions and methods such as [std::str::from_utf8](
 http://static.rust-lang.org/doc/master/std/str/fn.from_utf8.html) that
 may succeed and give a result, or fail when the input is invalid.

 1. Sometimes we assume the input is valid and don’t want to deal with
 the error case. Task failure works nicely.

 2. Sometimes we do want to do something different on invalid input, so
 returning an `OptionT` works best.

 And so we end up with both `from_utf8` and `from_utf8`. This particular
 case is worse because we also have `from_utf8_owned` and
 `from_utf8_owned_opt`, to cover everything.

 Multiplying names like this is just not good design. I’d like to reduce
 this pattern.

 Getting behavior 1. when you have 2. is easy: just call `.unwrap()` on
 the Option. I think we should rename every `foo_opt()` function or method
 to just `foo`, remove the old `foo()` behavior, and tell people (through
 documentation) to use `foo().unwrap()` if they want it back?

 The downsides are that unwrap is more verbose and gives less helpful
 error messages on task failure. But I think it’s worth it.

 What do you think?

 (PS: I’m guilty of making this worse in #10828, but I’d like to discuss
 this before sending pull requests with invasive API changes.)

 --
 Simon Sapin
 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev



 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev


___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2014-01-07 Thread Timothy Jones
On 8/01/2014, at 3:39 pm, Nick Cameron li...@ncameron.org wrote:

 I think that you eventually have to deal with the Some or None-ness of an 
 expression is an advantage of the ? operator, it means you can't ignore 
 failure, but you don't have to deal with it at every step of a compound 
 expression. Using an operator for unwrap has the same disadvantage as plain 
 unwrap - it lets you ignore the failure case.

It's also worth pointing out that ? and do-notation solve different problems. ? 
is addressing that there's no partial application of the dot operator, so you 
can't write `maybe.and_then(.next)`. In do-notation, you'd still have to name 
the value inside the option.

You can produce a limited form of the refutable do-notation with a macro:

macro_rules! refute (
(let $bind:pat = $val:expr; $(let $rbind:pat = $rval:expr);+; $result:expr) 
=
(match $val {
$bind = refute!($(let $rbind = $rval);+; $result),
fail = fail
});
(let $bind:pat = $val:expr; $result:expr) =
(match $val {
$bind = $result,
fail = fail
});
)

fn add_opts(x: Optionint, y: Optionint) - Optionint {
refute!(
let Some(a) = x;
let Some(b) = y;
Some(a + b)
)
}

Chaining the ? operator can't really be done in a tidy manner without having it 
be part of the language. `?.` has been really useful in CoffeeScript, and Rust 
has the advantage of being able to tie it into a trait and allow any relevant 
type to use it.

-- 
Tim
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2014-01-07 Thread Carter Schonwald
 I realized something. A good near term working solution could make use of
the pending procedural macros to make a nicer syntax for the and_then
procedures!

(or could the current syntax rules style macros work with that even?). Not
sure If i'll have the time to do that experiment,
but throwing the idea out there.




On Tuesday, January 7, 2014, Vadim wrote:

  I can see how '?.' would work when foo() returns a struct, but what
 about non-struct types, e.g. Optioni32 ?   Also, you'd still have to deal
 with 'None' at the end of the chain.   I think in most cases I'd rather
 have it fail.

 I also don't really like refutable let-patterns proposal, because stuff
 like let Some(x) = foo(); does not work with chaining when foo() returns
 a struct (and is still pretty wordy).

 Maybe we need an operator for getting wrapped value?   This would be
 similar to deref for [smart]pointers, except I think it should be a
 postfix operator to allow for easy chaining.   Let's say we chose '^' for
 this purpose, and implemented its' trait for Option, Result, etc.  Then one
 could write:
 let x = foo()^;
 or
 let y = foo()^.field;

 Vadim



 On Tue, Jan 7, 2014 at 11:30 AM, Nick Cameron li...@ncameron.org wrote:

 I agree with Simon that doubling the API is inelegant. I think the
 solution is adding sugar to make working with Option/Result easier -
 (semi-)independent of the foo/foo_opt issue, I find working with Option
 pretty painful.

 I prefer the Haskell do sugar to refutable patterns in let. Similar in
 spirit is the ? operator from Groovy, which I think is elegant and simple,
 it is an alternative to the . operator for field access/method call. In
 Rust it would have the following type and semantics:

 \Gamma e : OptionT'
 fType(T', f) = T
 
 \Gamma e?f : OptionT

 e?f ~~ match e { Somee = Somee.f, None = None }

 and similarly for method call.

 The ? operator has the same advantages and disadvantages as Haskell's do,
 but is more concise.

 Just another alternative to consider.


 On Sat, Dec 7, 2013 at 9:41 AM, Simon Sapin simon.sa...@exyr.org wrote:

 We have some functions and methods such as [std::str::from_utf8](http://
 static.rust-lang.org/doc/master/std/str/fn.from_utf8.html) that may
 succeed and give a result, or fail when the input is invalid.

 1. Sometimes we assume the input is valid and don’t want to deal with
 the error case. Task failure works nicely.

 2. Sometimes we do want to do something different on invalid input, so
 returning an `OptionT` works best.

 And so we end up with both `from_utf8` and `from_utf8`. This particular
 case is worse because we also have `from_utf8_owned` and
 `from_utf8_owned_opt`, to cover everything.

 Multiplying names like this is just not good design. I’d like to reduce
 this pattern.

 Getting behavior 1. when you have 2. is easy: just call `.unwrap()` on
 the Option. I think we should rename every `foo_opt()` function or method
 to just `foo`, remove the old `foo()` behavior, and tell people (through
 documentation) to use `foo().unwrap()` if they want it back?

 The downsides are that unwrap is more verbose and gives less helpful
 error messages on task failure. But I think it’s worth it.

 What do you think?

 (PS: I’m guilty of making this worse in #10828, but I’d like to discuss
 this before sending pull requests with invasive API changes.)

 --
 Simon Sapin
 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev



 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev



___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2014-01-07 Thread Nick Cameron
Sorry, I didn't mean ignore errors as in unsafe, I meant that it allows the
programmer to write code without having the error case be explicit. This is
the (well, one of the) problems with null pointers in C and Java.

You make a good point about errors from the API, and I guess this
highlights a worthwhile difference between expected None (e.g., a fn which
returns the age of a user, but the user could leave the field unspecified)
and an exceptional None (the same method fails to connect to the database).
It is perhaps worth having different mechanisms to deal with the two cases.


Cheers, Nick


On Wed, Jan 8, 2014 at 4:31 PM, Vadim vadi...@gmail.com wrote:

 On Tue, Jan 7, 2014 at 6:39 PM, Nick Cameron li...@ncameron.org wrote:

 I think that you eventually have to deal with the Some or None-ness of an
 expression is an advantage of the ? operator, it means you can't ignore
 failure, but you don't have to deal with it at every step of a compound
 expression. Using an operator for unwrap has the same disadvantage as plain
 unwrap - it lets you ignore the failure case.


 First of all, it does not let me ignore errors - if I try to unwrap() a
 None, it will kill my program (or at least the current task).   Whether
 this is what I want, depends on the use case.   In my experience, more
 often than not, an error returned by an API represents a bug in the
 program.  So what am I gonna do when I see that something has error'ed
 out?  I will probably just call fail!().

 Anyways, I think this thread was about how to avoid having both foo() and
 foo_opt() versions of every API, and many people (including myself),
 consider unwrap() too noisy.  So...

 Vadim




 On Wed, Jan 8, 2014 at 1:42 PM, Vadim vadi...@gmail.com wrote:

 I can see how '?.' would work when foo() returns a struct, but what
 about non-struct types, e.g. Optioni32 ?   Also, you'd still have to deal
 with 'None' at the end of the chain.   I think in most cases I'd rather
 have it fail.

 I also don't really like refutable let-patterns proposal, because stuff
 like let Some(x) = foo(); does not work with chaining when foo() returns
 a struct (and is still pretty wordy).

 Maybe we need an operator for getting wrapped value?   This would be
 similar to deref for [smart]pointers, except I think it should be a
 postfix operator to allow for easy chaining.   Let's say we chose '^' for
 this purpose, and implemented its' trait for Option, Result, etc.  Then one
 could write:
 let x = foo()^;
 or
 let y = foo()^.field;

 Vadim



 On Tue, Jan 7, 2014 at 11:30 AM, Nick Cameron li...@ncameron.orgwrote:

 I agree with Simon that doubling the API is inelegant. I think the
 solution is adding sugar to make working with Option/Result easier -
 (semi-)independent of the foo/foo_opt issue, I find working with Option
 pretty painful.

 I prefer the Haskell do sugar to refutable patterns in let. Similar in
 spirit is the ? operator from Groovy, which I think is elegant and simple,
 it is an alternative to the . operator for field access/method call. In
 Rust it would have the following type and semantics:

 \Gamma e : OptionT'
 fType(T', f) = T
 
 \Gamma e?f : OptionT

 e?f ~~ match e { Somee = Somee.f, None = None }

 and similarly for method call.

 The ? operator has the same advantages and disadvantages as Haskell's
 do, but is more concise.

 Just another alternative to consider.


 On Sat, Dec 7, 2013 at 9:41 AM, Simon Sapin simon.sa...@exyr.orgwrote:

 We have some functions and methods such as [std::str::from_utf8](
 http://static.rust-lang.org/doc/master/std/str/fn.from_utf8.html)
 that may succeed and give a result, or fail when the input is invalid.

 1. Sometimes we assume the input is valid and don’t want to deal with
 the error case. Task failure works nicely.

 2. Sometimes we do want to do something different on invalid input, so
 returning an `OptionT` works best.

 And so we end up with both `from_utf8` and `from_utf8`. This
 particular case is worse because we also have `from_utf8_owned` and
 `from_utf8_owned_opt`, to cover everything.

 Multiplying names like this is just not good design. I’d like to
 reduce this pattern.

 Getting behavior 1. when you have 2. is easy: just call `.unwrap()` on
 the Option. I think we should rename every `foo_opt()` function or method
 to just `foo`, remove the old `foo()` behavior, and tell people (through
 documentation) to use `foo().unwrap()` if they want it back?

 The downsides are that unwrap is more verbose and gives less helpful
 error messages on task failure. But I think it’s worth it.

 What do you think?

 (PS: I’m guilty of making this worse in #10828, but I’d like to
 discuss this before sending pull requests with invasive API changes.)

 --
 Simon Sapin
 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev



 ___
 Rust-dev 

Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-24 Thread Lars Bergstrom
On Dec 23, 2013, at 11:23 AM, Patrick Walton pcwal...@mozilla.com wrote:
 
 On 12/23/13 4:12 AM, Gábor Lehel wrote:
 I don't like either that (a) the possible failure is silent, and
 refutable lets look the same as irrefutable ones, nor (b) baking fail!()
 into the semantics. Haskell has these also and I think it's a wart. The
 proposed syntax solves both issues.
 
 For what it's worth, Rust's pattern matching is pretty heavily based on 
 OCaml's and the OCaml compiler complains with a warning if you use a 
 refutable pattern in `let`.

At the time SML and Caml made those decisions, neither language provided stack 
backtraces. According to the folks I've asked about it, the reason that 
refutable patterns in let bindings were left in there with a warning was that 
if you called Option.valOf on NONE, you just get:
uncaught exception Option
  raised at: Basis/Implementation/option.sml:17.25-17.31
- 

And the debugging is a real pain because you failed in the basis library 
doesn't help you track it down and you're pretty much stuck with 
printf-debugging (because there were also no debuggers / breakpoints). Whereas 
if you fail on the binding, the exception is thrown on the line where the 
binding attempt occurred:
uncaught exception Bind [nonexhaustive binding failure]
  raised at: stdIn:1.10-3.10
- 

This was supposedly an especially contentious decision in the SML language 
design meetings.

Given that modern ML implementations at least have the option to provide stack 
backtraces in debugging builds, the people I've talked to have said they would 
probably not allow refutable patterns today because large codebases written in 
this style end up with hundreds to thousands of ignorable warnings in their 
output, which both looks ugly and drowns out any real warnings. But, they can't 
change things now because it would break too much legacy code.
- Lars
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-24 Thread Carter Schonwald
This is a very good point.  Many of those same issues apply in Haskell too.

Additionally, the examples people have given for refutable let thus far all
seem to be special cases of a do notation / computation expression /
monadic abstraction.

That said, unless a special builtin trait is made, that line of
recommendation seems like it's not viable until rusts type system gets a
bit more enriched, what with higher kinded types being needed etc.

On Tuesday, December 24, 2013, Lars Bergstrom wrote:

 On Dec 23, 2013, at 11:23 AM, Patrick Walton 
 pcwal...@mozilla.comjavascript:;
 wrote:
 
  On 12/23/13 4:12 AM, Gábor Lehel wrote:
  I don't like either that (a) the possible failure is silent, and
  refutable lets look the same as irrefutable ones, nor (b) baking fail!()
  into the semantics. Haskell has these also and I think it's a wart. The
  proposed syntax solves both issues.
 
  For what it's worth, Rust's pattern matching is pretty heavily based on
 OCaml's and the OCaml compiler complains with a warning if you use a
 refutable pattern in `let`.

 At the time SML and Caml made those decisions, neither language provided
 stack backtraces. According to the folks I've asked about it, the reason
 that refutable patterns in let bindings were left in there with a warning
 was that if you called Option.valOf on NONE, you just get:
 uncaught exception Option
   raised at: Basis/Implementation/option.sml:17.25-17.31
 -

 And the debugging is a real pain because you failed in the basis library
 doesn't help you track it down and you're pretty much stuck with
 printf-debugging (because there were also no debuggers / breakpoints).
 Whereas if you fail on the binding, the exception is thrown on the line
 where the binding attempt occurred:
 uncaught exception Bind [nonexhaustive binding failure]
   raised at: stdIn:1.10-3.10
 -

 This was supposedly an especially contentious decision in the SML language
 design meetings.

 Given that modern ML implementations at least have the option to provide
 stack backtraces in debugging builds, the people I've talked to have said
 they would probably not allow refutable patterns today because large
 codebases written in this style end up with hundreds to thousands of
 ignorable warnings in their output, which both looks ugly and drowns out
 any real warnings. But, they can't change things now because it would break
 too much legacy code.
 - Lars
 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org javascript:;
 https://mail.mozilla.org/listinfo/rust-dev

___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-23 Thread Stefan Plantikow


Hi,

Am 23.12.2013 um 10:11 schrieb Masklinn maskl...@masklinn.net:

 
 On 2013-12-23, at 05:12 , Corey Richardson co...@octayn.net wrote:
 
 I find the ability to have refutable let
 
 I may have missed it, but is there a reason not to have just that? Make
 let similar to Erlang’s `=` and fail on refutation?
 

I didn’t understand this to be about wether let should accept refutable 
patterns in general. Rather this is about wether there should be additional 
syntax for refutable patterns. The decision to make irrefutable let the default 
seems reasonable as it avoids silent breakage when new variants are introduced 
for an enum type.

 You said you find the basic let’s irrefutability to be a useful property
 but have not explained why, and why it makes sense to introduce a
 separate-but-similar construct with subtly different semantics
 (I also see this as a possible failure, would users of the language
 really expect `let` to be irrefutable and `let [else]` to be refutable,
 or would they expect `let [else]` to allow returning a value and `let`
 to just fail on mismatch? If such different semantics are desired,
 I’d suggest using a different keyword entirely)
 
 more compelling than the
 ability to work around it with functions wrapping `match`
 
 That assertion seems ill supported so far: just about every example is
 in terms of `Option`, and `Option` is the one type which does not need a
 refutable let, owing to its truckload of convenience methods covering
 just about every basic use cases the only reasons to use a `match` with
 Option are personal preferences and insufficient knowledge of the type.
 

Sure, this discussion has used Option as a running example. I guess the more 
interesting use case is a library defined type without an unwrap() or similar 
method. A client of the library could of course implement his own helper method 
to solve that issue - or just use a variant of let with refutable patterns.

The benefit of the refutable patterns would be less boilerplate for helper 
methods like unwrap(), the ability to „unwrap“ any type, and a nice syntax for 
trying multiple values in succession ( let Some(x) =? try_1(), try_2(), fail() 
).  


Cheers,


Stefan.___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-23 Thread Gábor Lehel
On Mon, Dec 23, 2013 at 10:11 AM, Masklinn maskl...@masklinn.net wrote:


 On 2013-12-23, at 05:12 , Corey Richardson co...@octayn.net wrote:

  I find the ability to have refutable let

 I may have missed it, but is there a reason not to have just that? Make
 let similar to Erlang’s `=` and fail on refutation?


I don't like either that (a) the possible failure is silent, and refutable
lets look the same as irrefutable ones, nor (b) baking fail!() into the
semantics. Haskell has these also and I think it's a wart. The proposed
syntax solves both issues.

Rust doesn't allow partial matches in `match`es either, for reasons, so I
think it would be pretty strange to turn around and silently allow them in
`let`s.

The strongest arguments against IMHO are YAGNI (which is why I prefaced the
whole thing with *if* there's demand for a refutable let), and the
ambiguity with `if` (which is a technical issue that may or may not have a
satisfactory solution).

A meta-level process question: now that we have the `feature` attribute,
wouldn't that be a great way to empirically decide questions like these?
Implement the feature, put it behind a feature gate, and see how much use
it gets, and/or if there are any problems with it? This isn't the first
case where it seems like that might be more productive than trying to
anticipate all of the answers from theory alone. And it seems to work
pretty well for GHC. Just perhaps we could be more aggressive about
removing features which weren't successful.



 You said you find the basic let’s irrefutability to be a useful property
 but have not explained why, and why it makes sense to introduce a
 separate-but-similar construct with subtly different semantics
 (I also see this as a possible failure, would users of the language
 really expect `let` to be irrefutable and `let [else]` to be refutable,
 or would they expect `let [else]` to allow returning a value and `let`
 to just fail on mismatch? If such different semantics are desired,
 I’d suggest using a different keyword entirely)


If I'm understanding you correctly, this is a problem that would solve
itself: if someone thinks a plain `let` is refutable and will just fail on
mismatch, the compiler will quickly tell her otherwise.



  more compelling than the
  ability to work around it with functions wrapping `match`

 That assertion seems ill supported so far: just about every example is
 in terms of `Option`, and `Option` is the one type which does not need a
 refutable let, owing to its truckload of convenience methods covering
 just about every basic use cases the only reasons to use a `match` with
 Option are personal preferences and insufficient knowledge of the type.

  On Sun, Dec 22, 2013 at 11:00 PM, Carter Schonwald
  carter.schonw...@gmail.com wrote:
  Agreed!
 
 
  On Sunday, December 22, 2013, Ziad Hatahet wrote:
 
  But we already have Option::unwrap_or() and Option::unwrap_or_else()
 that
  behave similar to the 'else' syntax suggested above.
 
  --
  Ziad
 
 
  On Sun, Dec 22, 2013 at 10:37 AM, Léo Testard leo.test...@gmail.com
  wrote:
 
  Hello,
 
  Le 22 déc. 2013 à 18:59, Stefan Plantikow stefan.planti...@gmail.com
 a
  écrit :
 
  Hi,
 
  Am 22.12.2013 um 16:47 schrieb Gábor Lehel glaebho...@gmail.com:
 
  This is a nice idea.  At first I thought it wouldn’t work with `if`
 but
  in expressions `if` requires `else` so the grammar wouldn’t be
 ambiguous:
 
 
  No, it doesn't. As long as the if's true block returns unit.
  let foo = if ... { }; is perfectly legal, even it doesn't make much
 sense
  in practice.
 
  Leo
 
  ___
  Rust-dev mailing list
  Rust-dev@mozilla.org
  https://mail.mozilla.org/listinfo/rust-dev
 
 
 
  ___
  Rust-dev mailing list
  Rust-dev@mozilla.org
  https://mail.mozilla.org/listinfo/rust-dev
 
  ___
  Rust-dev mailing list
  Rust-dev@mozilla.org
  https://mail.mozilla.org/listinfo/rust-dev

 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev

___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-23 Thread Gábor Lehel
On Sun, Dec 22, 2013 at 7:37 PM, Léo Testard leo.test...@gmail.com wrote:

 Hello,

 Le 22 déc. 2013 à 18:59, Stefan Plantikow stefan.planti...@gmail.com a
 écrit :

  Hi,
 
  Am 22.12.2013 um 16:47 schrieb Gábor Lehel glaebho...@gmail.com:
 
  This is a nice idea.  At first I thought it wouldn’t work with `if` but
 in expressions `if` requires `else` so the grammar wouldn’t be ambiguous:
 

 No, it doesn't. As long as the if's true block returns unit.
 let foo = if ... { }; is perfectly legal, even it doesn't make much sense
 in practice.

 Leo


Thinking about this, if we say that `else` following a `let` is allowed if
*and only if* the pattern is refutable, then this wouldn't actually be
ambiguous, because something of type `()` can never be refutable. Therefore
`let ... = if { ... } else { ... };` can only be legal if the `else`
belongs to the `if`.

I'm not completely clear on the relationship between grammatic and semantic
ambiguity. Would the grammar still be ambiguous in this case? I would
naively think that you're not allowed to take types and such into account
at the grammar level, but Rust seemingly already does so w.r.t. whether or
not things (such as `if`) return `()`, so I'm a little bit confused. Can
someone explain?




 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev


___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-23 Thread Jack Moffitt
 I may have missed it, but is there a reason not to have just that? Make
 let similar to Erlang’s `=` and fail on refutation?

Erlang is designed around handling failure. It has links, monitors,
supervisors, and so forth. Rust has only some very basic tools for
catching the failure of a task.

I'll also note, that because Erlang has pattern matching in the
clauses themselves, many failures occur even before the function
bodies.

Some of those features incur non-trivial runtime costs which is why
Rust doesn't have them.

jack.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-23 Thread Patrick Walton

On 12/23/13 4:12 AM, Gábor Lehel wrote:

I don't like either that (a) the possible failure is silent, and
refutable lets look the same as irrefutable ones, nor (b) baking fail!()
into the semantics. Haskell has these also and I think it's a wart. The
proposed syntax solves both issues.


For what it's worth, Rust's pattern matching is pretty heavily based on 
OCaml's and the OCaml compiler complains with a warning if you use a 
refutable pattern in `let`.


Patrick

___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-23 Thread Carter Schonwald
that seems like a reasonable balance


On Mon, Dec 23, 2013 at 12:23 PM, Patrick Walton pcwal...@mozilla.comwrote:

 On 12/23/13 4:12 AM, Gábor Lehel wrote:

 I don't like either that (a) the possible failure is silent, and
 refutable lets look the same as irrefutable ones, nor (b) baking fail!()
 into the semantics. Haskell has these also and I think it's a wart. The
 proposed syntax solves both issues.


 For what it's worth, Rust's pattern matching is pretty heavily based on
 OCaml's and the OCaml compiler complains with a warning if you use a
 refutable pattern in `let`.

 Patrick


 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev

___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-23 Thread Benjamin Striegel
 the OCaml compiler complains with a warning if you use a refutable
pattern in `let`.

And what does OCaml do at runtime if the pattern is refuted?


On Mon, Dec 23, 2013 at 12:23 PM, Patrick Walton pcwal...@mozilla.comwrote:

 On 12/23/13 4:12 AM, Gábor Lehel wrote:

 I don't like either that (a) the possible failure is silent, and
 refutable lets look the same as irrefutable ones, nor (b) baking fail!()
 into the semantics. Haskell has these also and I think it's a wart. The
 proposed syntax solves both issues.


 For what it's worth, Rust's pattern matching is pretty heavily based on
 OCaml's and the OCaml compiler complains with a warning if you use a
 refutable pattern in `let`.

 Patrick


 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev

___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-23 Thread Patrick Walton

On 12/23/13 10:48 AM, Benjamin Striegel wrote:

  the OCaml compiler complains with a warning if you use a refutable
pattern in `let`.

And what does OCaml do at runtime if the pattern is refuted?


Throws.

Patrick


___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-23 Thread Gábor Lehel
That seems like a nice compromise, but I don't think it's a good one.
Either you intended the pattern to be refutable or you didn't. If you
didn't and it is, you should get an error, not a warning. If you did, you
shouldn't get a warning at all. Are you going to put a compiler pragma to
disable the warning at every use site where you intentionally want a let to
be refutable? At that point, you might as well have separate syntax for
refutable and irrefutable lets. Or are you just going to live with having
false positive warnings in your code?

(FWIW, I'm basically fine with having only irrefutable lets, and using
`match` for the other cases, or in other words the status quo. But if we
*do* add refutable lets, I strongly think they should be explicit.)


On Mon, Dec 23, 2013 at 7:03 PM, Carter Schonwald 
carter.schonw...@gmail.com wrote:

 that seems like a reasonable balance


 On Mon, Dec 23, 2013 at 12:23 PM, Patrick Walton pcwal...@mozilla.comwrote:

 On 12/23/13 4:12 AM, Gábor Lehel wrote:

 I don't like either that (a) the possible failure is silent, and
 refutable lets look the same as irrefutable ones, nor (b) baking fail!()
 into the semantics. Haskell has these also and I think it's a wart. The
 proposed syntax solves both issues.


 For what it's worth, Rust's pattern matching is pretty heavily based on
 OCaml's and the OCaml compiler complains with a warning if you use a
 refutable pattern in `let`.


 Patrick


 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev



 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev


___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-23 Thread Benjamin Striegel
I too think it would be a big mistake to allow let patterns to be
refutable, when we've already tried and rejected allowing the same in match
statements (ancient Rust history quiz: who else remembers `match check`?).


On Mon, Dec 23, 2013 at 2:44 PM, Gábor Lehel glaebho...@gmail.com wrote:

 That seems like a nice compromise, but I don't think it's a good one.
 Either you intended the pattern to be refutable or you didn't. If you
 didn't and it is, you should get an error, not a warning. If you did, you
 shouldn't get a warning at all. Are you going to put a compiler pragma to
 disable the warning at every use site where you intentionally want a let to
 be refutable? At that point, you might as well have separate syntax for
 refutable and irrefutable lets. Or are you just going to live with having
 false positive warnings in your code?

 (FWIW, I'm basically fine with having only irrefutable lets, and using
 `match` for the other cases, or in other words the status quo. But if we
 *do* add refutable lets, I strongly think they should be explicit.)



 On Mon, Dec 23, 2013 at 7:03 PM, Carter Schonwald 
 carter.schonw...@gmail.com wrote:

 that seems like a reasonable balance


 On Mon, Dec 23, 2013 at 12:23 PM, Patrick Walton pcwal...@mozilla.comwrote:

 On 12/23/13 4:12 AM, Gábor Lehel wrote:

 I don't like either that (a) the possible failure is silent, and
 refutable lets look the same as irrefutable ones, nor (b) baking fail!()
 into the semantics. Haskell has these also and I think it's a wart. The
 proposed syntax solves both issues.


 For what it's worth, Rust's pattern matching is pretty heavily based on
 OCaml's and the OCaml compiler complains with a warning if you use a
 refutable pattern in `let`.


 Patrick


 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev



 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev



 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev


___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-23 Thread Simon Sapin

On 23/12/2013 20:55, Benjamin Striegel wrote:

I too think it would be a big mistake to allow let patterns to be
refutable, when we've already tried and rejected allowing the same in
match statements (ancient Rust history quiz: who else remembers `match
check`?).


For those of us that were not around or do not remember, can you explain 
what was tried and rejected?


I sometimes find myself writing a `_ = ()` arm for match and wish it 
could be implied… and sometimes `_ = fail!()`. That the two are 
sometimes used is probably a sign that the status quo (require it to be 
explicit) is better.


--
Simon Sapin
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-23 Thread Benjamin Striegel
 For those of us that were not around or do not remember, can you explain
what was tried and rejected?

Heh, it was so long ago that I forgot that the `match` keyword used to be
`alt`. Here's the relevant section from the 0.1 manual (Jan 2012):

https://github.com/mozilla/rust/blob/16e4369fe3b5f00aa3cdc584a4e41c51c0d3ca8a/doc/tutorial.md#pattern-matching

If the arm with the wildcard pattern was left off in the above example,
running it on a number greater than ten (or negative) would cause a
run-time failure. When no arm matches, alt constructs do not silently fall
through—they blow up instead.

Back then, we had no facility to statically force exhaustiveness. This
changed in 0.2, when exhaustive matches became the default, though you
could still opt-in to non-exhaustive matches by using `alt check` rather
than `alt`.

https://github.com/mozilla/rust/blob/619c4fce891f31ec234a3ac162d40d3def95956e/RELEASES.txt#L581

Indeed, as you mention, at the time people were worried that this would
lead to widespread proliferation of `_ = fail`, especially for uses such
as matching on integers, which we lack the facilities to exhaustively
check. However, in the years since, I can remember only a single person
noticing this and lamenting it, and the peace of mind provided by
statically-checked exhaustiveness is certainly pleasant. Furthermore, so
few people opted-in to dynamic checking via `alt check` that we had dropped
the functionality entirely by 0.4.


On Mon, Dec 23, 2013 at 3:40 PM, Simon Sapin simon.sa...@exyr.org wrote:

 On 23/12/2013 20:55, Benjamin Striegel wrote:

 I too think it would be a big mistake to allow let patterns to be
 refutable, when we've already tried and rejected allowing the same in
 match statements (ancient Rust history quiz: who else remembers `match
 check`?).


 For those of us that were not around or do not remember, can you explain
 what was tried and rejected?

 I sometimes find myself writing a `_ = ()` arm for match and wish it
 could be implied… and sometimes `_ = fail!()`. That the two are sometimes
 used is probably a sign that the status quo (require it to be explicit) is
 better.

 --
 Simon Sapin

 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev

___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-22 Thread Gábor Lehel
Using `match` works well enough, but if there's demand for a refutable
`let` which is lighter-weight, what about:

let Some(result) = from_utf8(some_bytes) else fail!();

In other words, if the `let` pattern is refutable, you have to provide
something `else` with return type `!` as the alternative for when the `let`
fails to match.


(I could imagine that being generalized to any number of `else`s of which
only the last returns `!` (i.o.w. never returns), for example

let Some(result) = from_utf8(some_bytes) else
from_utf8(some_other_bytes) else fail!();

and/or to allowing anything `else` which always matches, e.g.

let Some(result) = from_utf8(some_bytes) else Some(default);

of which anything that returns `!` would be only a special case. But
these have progressively diminishing returns, and I'm merely mentioning,
not endorsing them.)


On Tue, Dec 17, 2013 at 9:11 PM, Kevin Ballard ke...@sb.org wrote:

 On Dec 17, 2013, at 11:37 AM, Stefan Plantikow stefan.planti...@gmail.com
 wrote:

 Hi,

 Am 17.12.2013 um 20:10 schrieb Corey Richardson co...@octayn.net:

 On Tue, Dec 17, 2013 at 2:06 PM, Stefan Plantikow
 stefan.planti...@gmail.com wrote:

 Hi,


 Am 09.12.2013 um 16:53 schrieb Damien Radtke damienrad...@gmail.com:

 I have no idea if it would be feasible in the standard library, but
 wouldn't the ideal solution be having one function (e.g. from_utf8()) that
 could return two possible values, a bare result and an Option? Letting the
 compiler decide which version to use based on type inference like this:

let result: ~str = from_utf8(...);
let result: Option~str = from_utf8(...);

 Assuming both of them are passed invalid UTF8, then the first version
 would fail, but the second version would just return None.




 We already have pattern matching in `let` (the LHS is a pattern), but
 it's only for irrefutable patterns. IOW, `let` can never fail, and
 that's a very very useful property IMO.


 oh ok I haven’t kept up on the syntax then. Given the utility of
 destructuring bind for error handling, wouldn't it make sense to have a
 variant of let that can fail?

 Now syntax is a matter of practicality and taste but spontaneously this
 comes to mind:

let opt Some(~result) = from_utf8(..)

 comes to mind.


 You can do it with a bit more verbosity, which I think is perfectly fine
 as it makes failure much more obvious.

 let result = match from_utf8(..) {
 Some(~result) = result,
 _ = fail!(b0rk b0rk b0rk)
 };

 Of course, in this particular example, you'd probably just write

 let result = from_utf8(..).unwrap();

 but the longer match form will work for other enums.

 -Kevin

 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev


___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-22 Thread Gaetan
That is pretty elegant.
Le 22 déc. 2013 16:47, Gábor Lehel glaebho...@gmail.com a écrit :

 Using `match` works well enough, but if there's demand for a refutable
 `let` which is lighter-weight, what about:

 let Some(result) = from_utf8(some_bytes) else fail!();

 In other words, if the `let` pattern is refutable, you have to provide
 something `else` with return type `!` as the alternative for when the `let`
 fails to match.


 (I could imagine that being generalized to any number of `else`s of which
 only the last returns `!` (i.o.w. never returns), for example

 let Some(result) = from_utf8(some_bytes) else
 from_utf8(some_other_bytes) else fail!();

 and/or to allowing anything `else` which always matches, e.g.

 let Some(result) = from_utf8(some_bytes) else Some(default);

 of which anything that returns `!` would be only a special case. But
 these have progressively diminishing returns, and I'm merely mentioning,
 not endorsing them.)


 On Tue, Dec 17, 2013 at 9:11 PM, Kevin Ballard ke...@sb.org wrote:

 On Dec 17, 2013, at 11:37 AM, Stefan Plantikow 
 stefan.planti...@gmail.com wrote:

 Hi,

 Am 17.12.2013 um 20:10 schrieb Corey Richardson co...@octayn.net:

 On Tue, Dec 17, 2013 at 2:06 PM, Stefan Plantikow
 stefan.planti...@gmail.com wrote:

 Hi,


 Am 09.12.2013 um 16:53 schrieb Damien Radtke damienrad...@gmail.com:

 I have no idea if it would be feasible in the standard library, but
 wouldn't the ideal solution be having one function (e.g. from_utf8()) that
 could return two possible values, a bare result and an Option? Letting the
 compiler decide which version to use based on type inference like this:

let result: ~str = from_utf8(...);
let result: Option~str = from_utf8(...);

 Assuming both of them are passed invalid UTF8, then the first version
 would fail, but the second version would just return None.




 We already have pattern matching in `let` (the LHS is a pattern), but
 it's only for irrefutable patterns. IOW, `let` can never fail, and
 that's a very very useful property IMO.


 oh ok I haven’t kept up on the syntax then. Given the utility of
 destructuring bind for error handling, wouldn't it make sense to have a
 variant of let that can fail?

 Now syntax is a matter of practicality and taste but spontaneously this
 comes to mind:

let opt Some(~result) = from_utf8(..)

 comes to mind.


 You can do it with a bit more verbosity, which I think is perfectly fine
 as it makes failure much more obvious.

 let result = match from_utf8(..) {
 Some(~result) = result,
 _ = fail!(b0rk b0rk b0rk)
 };

 Of course, in this particular example, you'd probably just write

 let result = from_utf8(..).unwrap();

 but the longer match form will work for other enums.

 -Kevin

 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev



 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev


___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-22 Thread Corey Richardson
I quite like this proposal, though I'd suggest that the else clause
is evaluated as the value for when the pattern fails. `!` would always
be substitutable there.

On Sun, Dec 22, 2013 at 10:47 AM, Gábor Lehel glaebho...@gmail.com wrote:
 Using `match` works well enough, but if there's demand for a refutable `let`
 which is lighter-weight, what about:

 let Some(result) = from_utf8(some_bytes) else fail!();

 In other words, if the `let` pattern is refutable, you have to provide
 something `else` with return type `!` as the alternative for when the `let`
 fails to match.


 (I could imagine that being generalized to any number of `else`s of which
 only the last returns `!` (i.o.w. never returns), for example

 let Some(result) = from_utf8(some_bytes) else
 from_utf8(some_other_bytes) else fail!();

 and/or to allowing anything `else` which always matches, e.g.

 let Some(result) = from_utf8(some_bytes) else Some(default);

 of which anything that returns `!` would be only a special case. But these
 have progressively diminishing returns, and I'm merely mentioning, not
 endorsing them.)


 On Tue, Dec 17, 2013 at 9:11 PM, Kevin Ballard ke...@sb.org wrote:

 On Dec 17, 2013, at 11:37 AM, Stefan Plantikow
 stefan.planti...@gmail.com wrote:

 Hi,

 Am 17.12.2013 um 20:10 schrieb Corey Richardson co...@octayn.net:

 On Tue, Dec 17, 2013 at 2:06 PM, Stefan Plantikow
 stefan.planti...@gmail.com wrote:

 Hi,


 Am 09.12.2013 um 16:53 schrieb Damien Radtke damienrad...@gmail.com:

 I have no idea if it would be feasible in the standard library, but
 wouldn't the ideal solution be having one function (e.g. from_utf8()) that
 could return two possible values, a bare result and an Option? Letting the
 compiler decide which version to use based on type inference like this:

let result: ~str = from_utf8(...);
let result: Option~str = from_utf8(...);

 Assuming both of them are passed invalid UTF8, then the first version
 would fail, but the second version would just return None.




 We already have pattern matching in `let` (the LHS is a pattern), but
 it's only for irrefutable patterns. IOW, `let` can never fail, and
 that's a very very useful property IMO.


 oh ok I haven’t kept up on the syntax then. Given the utility of
 destructuring bind for error handling, wouldn't it make sense to have a
 variant of let that can fail?

 Now syntax is a matter of practicality and taste but spontaneously this
 comes to mind:

let opt Some(~result) = from_utf8(..)

 comes to mind.


 You can do it with a bit more verbosity, which I think is perfectly fine
 as it makes failure much more obvious.

 let result = match from_utf8(..) {
 Some(~result) = result,
 _ = fail!(b0rk b0rk b0rk)
 };

 Of course, in this particular example, you'd probably just write

 let result = from_utf8(..).unwrap();

 but the longer match form will work for other enums.

 -Kevin

 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev



 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev

___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-22 Thread Stefan Plantikow
Hi,

Am 22.12.2013 um 16:47 schrieb Gábor Lehel glaebho...@gmail.com:

 Using `match` works well enough, but if there's demand for a refutable `let` 
 which is lighter-weight, what about:
 
 let Some(result) = from_utf8(some_bytes) else fail!();
 

This is a nice idea.  At first I thought it wouldn’t work with `if` but in 
expressions `if` requires `else` so the grammar wouldn’t be ambiguous:

let Some(result) = if cond { .. } else { … }  else fail();

 In other words, if the `let` pattern is refutable, you have to provide 
 something `else` with return type `!` as the alternative for when the `let` 
 fails to match.
 

Shouldn't the return be the same for all expressions? This would allow:

let Some(result) = from_utf8(some_bytes) else Some(defaultValue);



Stefan.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-22 Thread Léo Testard
Hello,

Le 22 déc. 2013 à 18:59, Stefan Plantikow stefan.planti...@gmail.com a écrit :

 Hi,
 
 Am 22.12.2013 um 16:47 schrieb Gábor Lehel glaebho...@gmail.com:
 
 This is a nice idea.  At first I thought it wouldn’t work with `if` but in 
 expressions `if` requires `else` so the grammar wouldn’t be ambiguous:
 

No, it doesn't. As long as the if's true block returns unit.
let foo = if ... { }; is perfectly legal, even it doesn't make much sense in 
practice.

Leo


signature.asc
Description: Message signed with OpenPGP using GPGMail
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-22 Thread Ziad Hatahet
But we already have Option::unwrap_or() and Option::unwrap_or_else() that
behave similar to the 'else' syntax suggested above.

--
Ziad


On Sun, Dec 22, 2013 at 10:37 AM, Léo Testard leo.test...@gmail.com wrote:

 Hello,

 Le 22 déc. 2013 à 18:59, Stefan Plantikow stefan.planti...@gmail.com a
 écrit :

  Hi,
 
  Am 22.12.2013 um 16:47 schrieb Gábor Lehel glaebho...@gmail.com:
 
  This is a nice idea.  At first I thought it wouldn’t work with `if` but
 in expressions `if` requires `else` so the grammar wouldn’t be ambiguous:
 

 No, it doesn't. As long as the if's true block returns unit.
 let foo = if ... { }; is perfectly legal, even it doesn't make much sense
 in practice.

 Leo

 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev


___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-22 Thread Carter Schonwald
Agreed!

On Sunday, December 22, 2013, Ziad Hatahet wrote:

 But we already have Option::unwrap_or() and Option::unwrap_or_else() that
 behave similar to the 'else' syntax suggested above.

 --
 Ziad


 On Sun, Dec 22, 2013 at 10:37 AM, Léo Testard 
 leo.test...@gmail.comjavascript:_e({}, 'cvml', 'leo.test...@gmail.com');
  wrote:

 Hello,

 Le 22 déc. 2013 à 18:59, Stefan Plantikow 
 stefan.planti...@gmail.comjavascript:_e({}, 'cvml', 
 'stefan.planti...@gmail.com');
 a écrit :

  Hi,
 
  Am 22.12.2013 um 16:47 schrieb Gábor Lehel 
  glaebho...@gmail.comjavascript:_e({}, 'cvml', 'glaebho...@gmail.com');
 :
 
  This is a nice idea.  At first I thought it wouldn’t work with `if` but
 in expressions `if` requires `else` so the grammar wouldn’t be ambiguous:
 

 No, it doesn't. As long as the if's true block returns unit.
 let foo = if ... { }; is perfectly legal, even it doesn't make much sense
 in practice.

 Leo

 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org javascript:_e({}, 'cvml', 'Rust-dev@mozilla.org');
 https://mail.mozilla.org/listinfo/rust-dev



___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-17 Thread Kevin Ballard
On Dec 17, 2013, at 11:37 AM, Stefan Plantikow stefan.planti...@gmail.com 
wrote:

 Hi,
 
 Am 17.12.2013 um 20:10 schrieb Corey Richardson co...@octayn.net:
 
 On Tue, Dec 17, 2013 at 2:06 PM, Stefan Plantikow
 stefan.planti...@gmail.com wrote:
 Hi,
 
 
 Am 09.12.2013 um 16:53 schrieb Damien Radtke damienrad...@gmail.com:
 
 I have no idea if it would be feasible in the standard library, but 
 wouldn't the ideal solution be having one function (e.g. from_utf8()) that 
 could return two possible values, a bare result and an Option? Letting the 
 compiler decide which version to use based on type inference like this:
 
let result: ~str = from_utf8(...);
let result: Option~str = from_utf8(...);
 
 Assuming both of them are passed invalid UTF8, then the first version 
 would fail, but the second version would just return None.
 
 
 
 We already have pattern matching in `let` (the LHS is a pattern), but
 it's only for irrefutable patterns. IOW, `let` can never fail, and
 that's a very very useful property IMO.
 
 oh ok I haven’t kept up on the syntax then. Given the utility of 
 destructuring bind for error handling, wouldn't it make sense to have a 
 variant of let that can fail? 
 
 Now syntax is a matter of practicality and taste but spontaneously this comes 
 to mind:
 
let opt Some(~result) = from_utf8(..)
 
 comes to mind.

You can do it with a bit more verbosity, which I think is perfectly fine as it 
makes failure much more obvious.

let result = match from_utf8(..) {
Some(~result) = result,
_ = fail!(b0rk b0rk b0rk)
};

Of course, in this particular example, you'd probably just write

let result = from_utf8(..).unwrap();

but the longer match form will work for other enums.

-Kevin

smime.p7s
Description: S/MIME cryptographic signature
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-17 Thread Stefan Plantikow
Hi,

Am 17.12.2013 um 20:10 schrieb Corey Richardson co...@octayn.net:

 On Tue, Dec 17, 2013 at 2:06 PM, Stefan Plantikow
 stefan.planti...@gmail.com wrote:
 Hi,
 
 
 Am 09.12.2013 um 16:53 schrieb Damien Radtke damienrad...@gmail.com:
 
 I have no idea if it would be feasible in the standard library, but 
 wouldn't the ideal solution be having one function (e.g. from_utf8()) that 
 could return two possible values, a bare result and an Option? Letting the 
 compiler decide which version to use based on type inference like this:
 
let result: ~str = from_utf8(...);
let result: Option~str = from_utf8(...);
 
 Assuming both of them are passed invalid UTF8, then the first version would 
 fail, but the second version would just return None.
 
 
 
 We already have pattern matching in `let` (the LHS is a pattern), but
 it's only for irrefutable patterns. IOW, `let` can never fail, and
 that's a very very useful property IMO.

oh ok I haven’t kept up on the syntax then. Given the utility of destructuring 
bind for error handling, wouldn't it make sense to have a variant of let that 
can fail? 

Now syntax is a matter of practicality and taste but spontaneously this comes 
to mind:

   let opt Some(~result) = from_utf8(..)

comes to mind.



Cheers,



Stefan.




___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-17 Thread Corey Richardson
On Tue, Dec 17, 2013 at 2:06 PM, Stefan Plantikow
stefan.planti...@gmail.com wrote:
 Hi,


 Am 09.12.2013 um 16:53 schrieb Damien Radtke damienrad...@gmail.com:

 I have no idea if it would be feasible in the standard library, but wouldn't 
 the ideal solution be having one function (e.g. from_utf8()) that could 
 return two possible values, a bare result and an Option? Letting the 
 compiler decide which version to use based on type inference like this:

 let result: ~str = from_utf8(...);
 let result: Option~str = from_utf8(...);

 Assuming both of them are passed invalid UTF8, then the first version would 
 fail, but the second version would just return None.


 If rust allowed pattern matching in let, this problem would go away:

   let Some(~result) = from_utf8(…);

 This would fail if from_utf8(..) would not return None. This solution has 
 several benefits:

 - The code clearly expresses intent (a result was expected and thus it should 
 fail if instead None is returned)
 - Only one function is needed and that functions signature covers all 
 possible return cases
 - This approach isn’t limited to Option and could very well also work with 
 Result.  The generated error message could contain the value that was not 
 matched (and thus have more detailed error information).
 - IMHO the required syntax change won't  break existing code (?)


We already have pattern matching in `let` (the LHS is a pattern), but
it's only for irrefutable patterns. IOW, `let` can never fail, and
that's a very very useful property IMO.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-09 Thread Damien Radtke
I have no idea if it would be feasible in the standard library, but
wouldn't the ideal solution be having one function (e.g. from_utf8()) that
could return two possible values, a bare result and an Option? Letting the
compiler decide which version to use based on type inference like this:

let result: ~str = from_utf8(...);
let result: Option~str = from_utf8(...);

Assuming both of them are passed invalid UTF8, then the first version would
fail, but the second version would just return None.

Again, I don't know if it's possible given the current implementation, but
I do think it would be helpful to have a picture of the ideal, and then
decide on whatever solution comes closest.

As a side note, even if the standard library sticks with two variants for
each option function, I would prefer the default one return an Option and
have the variant fail on invalid input. Task failure at runtime is a
nastier surprise than an invalid type error at compile time, especially for
new users who aren't entirely sure of the difference.


On Sun, Dec 8, 2013 at 11:58 AM, Carter Schonwald 
carter.schonw...@gmail.com wrote:

 Such sugar would would use some sort of monad trait right?


 On Sunday, December 8, 2013, Ziad Hatahet wrote:

 On Sat, Dec 7, 2013 at 2:21 PM, Gábor Lehel illiss...@gmail.com wrote:

 I do wonder whether it wouldn't make sense to add sugar for Option, at
 least eventually. (`int?` at the type level is really nice, too... too bad
 it doesn't play so well with Rust's sigils. Introducing the potential
 confusion between `~?T` and `?~T` is probably a step too far.)


 Wouldn't it be better to add something similar to Haskell's `do` instead
 of another sigil?


 --
 Ziad


 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev


___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-09 Thread spir

On 12/09/2013 04:53 PM, Damien Radtke wrote:

I have no idea if it would be feasible in the standard library, but
wouldn't the ideal solution be having one function (e.g. from_utf8()) that
could return two possible values, a bare result and an Option? Letting the
compiler decide which version to use based on type inference like this:

 let result: ~str = from_utf8(...);
 let result: Option~str = from_utf8(...);

Assuming both of them are passed invalid UTF8, then the first version would
fail, but the second version would just return None.

Again, I don't know if it's possible given the current implementation, but
I do think it would be helpful to have a picture of the ideal, [...]


This is indeed close to an ideal version ;-), isn't it?

Denis
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-09 Thread Simon Sapin

On 09/12/2013 15:53, Damien Radtke wrote:

I have no idea if it would be feasible in the standard library, but
wouldn't the ideal solution be having one function (e.g. from_utf8())
that could return two possible values, a bare result and an Option?
Letting the compiler decide which version to use based on type inference
like this:

 let result: ~str = from_utf8(...);
 let result: Option~str = from_utf8(...);

Assuming both of them are passed invalid UTF8, then the first version
would fail, but the second version would just return None.

Again, I don't know if it's possible given the current implementation,
but I do think it would be helpful to have a picture of the ideal, and
then decide on whatever solution comes closest.


It is possible to have a generic return value, see for example the 
.collect() method of iterators.


https://github.com/mozilla/rust/blob/4e0cb316fc980f00e1b74f3fdb7a842b540be280/src/libstd/iter.rs#L447

But it involves creating a trait, and implementing it for every 
supported type. IMO it’s a lot more involved than what we would want for 
every operation that may fail on invalid input.




As a side note, even if the standard library sticks with two variants
for each option function, I would prefer the default one return an
Option and have the variant fail on invalid input. Task failure at
runtime is a nastier surprise than an invalid type error at compile
time, especially for new users who aren't entirely sure of the difference.


--
Simon Sapin
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-09 Thread Gaetan

   let result: ~str = from_utf8(...);
   let result: Option~str = from_utf8(...);


That was what I called implicit unwrap. I however recommend ``let result
= from_utf8(...)`` to be the unwrapped version (ie, result is ~str)

Do you think it is possible to add this syntaxic sugar?

fn any_function() - Result~str
{

...

}

// When called :

let s = any_function(); // unwrap() is automatically called, s is a ~str
let res = any_function?(); // unwrap is not called, res is a Result~str
let res2: Result~str = any_function(); // unwrap is not called, res is a
Result~str
if res.is_ok() {
  let s2 = res.unwrap()
}

Or maybe a simpler version, but the semantic is reversed, where a?() means
a().unwrap():

let res = any_function(); // unwrap is not called, res is a Result~str
let s = any_function?(); // unwrap() is automatically called, s is a ~str



-
Gaetan



2013/12/9 Simon Sapin simon.sa...@exyr.org

 On 09/12/2013 15:53, Damien Radtke wrote:

 I have no idea if it would be feasible in the standard library, but
 wouldn't the ideal solution be having one function (e.g. from_utf8())
 that could return two possible values, a bare result and an Option?
 Letting the compiler decide which version to use based on type inference
 like this:

  let result: ~str = from_utf8(...);
  let result: Option~str = from_utf8(...);

 Assuming both of them are passed invalid UTF8, then the first version
 would fail, but the second version would just return None.

 Again, I don't know if it's possible given the current implementation,
 but I do think it would be helpful to have a picture of the ideal, and
 then decide on whatever solution comes closest.


 It is possible to have a generic return value, see for example the
 .collect() method of iterators.

 https://github.com/mozilla/rust/blob/4e0cb316fc980f00e1b74f3fdb7a84
 2b540be280/src/libstd/iter.rs#L447

 But it involves creating a trait, and implementing it for every supported
 type. IMO it’s a lot more involved than what we would want for every
 operation that may fail on invalid input.



  As a side note, even if the standard library sticks with two variants
 for each option function, I would prefer the default one return an
 Option and have the variant fail on invalid input. Task failure at
 runtime is a nastier surprise than an invalid type error at compile
 time, especially for new users who aren't entirely sure of the difference.


 --
 Simon Sapin

 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev

___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-09 Thread Daniel Micay
On Mon, Dec 9, 2013 at 10:53 AM, Damien Radtke damienrad...@gmail.com wrote:
 I have no idea if it would be feasible in the standard library, but wouldn't
 the ideal solution be having one function (e.g. from_utf8()) that could
 return two possible values, a bare result and an Option? Letting the
 compiler decide which version to use based on type inference like this:

 let result: ~str = from_utf8(...);
 let result: Option~str = from_utf8(...);

 Assuming both of them are passed invalid UTF8, then the first version would
 fail, but the second version would just return None.

 Again, I don't know if it's possible given the current implementation, but I
 do think it would be helpful to have a picture of the ideal, and then decide
 on whatever solution comes closest.

 As a side note, even if the standard library sticks with two variants for
 each option function, I would prefer the default one return an Option and
 have the variant fail on invalid input. Task failure at runtime is a nastier
 surprise than an invalid type error at compile time, especially for new
 users who aren't entirely sure of the difference.

I think this is too complex and error prone. I don't see the problem
with just using `Option` and then calling `get` (currently `unwrap`)
when you want to ignore the possibility of failure. The compiler
should be printing a failure stack trace but for now you can still get
one with `gdb`.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-08 Thread Ziad Hatahet
On Sat, Dec 7, 2013 at 2:21 PM, Gábor Lehel illiss...@gmail.com wrote:

 I do wonder whether it wouldn't make sense to add sugar for Option, at
 least eventually. (`int?` at the type level is really nice, too... too bad
 it doesn't play so well with Rust's sigils. Introducing the potential
 confusion between `~?T` and `?~T` is probably a step too far.)


Wouldn't it be better to add something similar to Haskell's `do` instead of
another sigil?


--
Ziad
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-08 Thread Gábor Lehel
On Sun, Dec 8, 2013 at 10:26 AM, Ziad Hatahet hata...@gmail.com wrote:

 On Sat, Dec 7, 2013 at 2:21 PM, Gábor Lehel illiss...@gmail.com wrote:

 I do wonder whether it wouldn't make sense to add sugar for Option, at
 least eventually. (`int?` at the type level is really nice, too... too bad
 it doesn't play so well with Rust's sigils. Introducing the potential
 confusion between `~?T` and `?~T` is probably a step too far.)


 Wouldn't it be better to add something similar to Haskell's `do` instead
 of another sigil?


...that's basically what I was saying.



 --
 Ziad




-- 
Your ship was destroyed in a monadic eruption.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-08 Thread Carter Schonwald
Such sugar would would use some sort of monad trait right?

On Sunday, December 8, 2013, Ziad Hatahet wrote:

 On Sat, Dec 7, 2013 at 2:21 PM, Gábor Lehel 
 illiss...@gmail.comjavascript:_e({}, 'cvml', 'illiss...@gmail.com');
  wrote:

 I do wonder whether it wouldn't make sense to add sugar for Option, at
 least eventually. (`int?` at the type level is really nice, too... too bad
 it doesn't play so well with Rust's sigils. Introducing the potential
 confusion between `~?T` and `?~T` is probably a step too far.)


 Wouldn't it be better to add something similar to Haskell's `do` instead
 of another sigil?


 --
 Ziad


___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-07 Thread Simon Sapin

On 07/12/2013 01:07, spir wrote:

Maybe it's only me, but this not at at all clear to my eyes. My imagined soluton
(for a totally different lang) was something like this, on the caller side:

ucodes = s.utf8_decode()!   // source should be correct, error on 
failure
  ucodes = s.utf8_decode()? // logical failure expected, return None or
whatnot



This is interesting, but I’d like to discuss what to do in this 
particular language, Rust that is trying to go to 1.0 and will probably 
not accept such syntax change :)


--
Simon Sapin
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-07 Thread Simon Sapin

On 07/12/2013 01:14, Huon Wilson wrote:

I personally think a better solution is something like Haskell's do
notation[1], where you can chain several computations that return
Option.. such that if any intermediate one returns None, the later
ones are not evaluated and the whole expression returns None, which
saves having to call .get()/.unwrap()/.expect() a lot.


We have that, it’s Option’s .and_then() method.



This can work for types like Result too (in fact, the Haskell
implementation of `do` is sugar around some monad functions, so any
monad can be used there; we currently don't have the power to express
the monad typeclass/trait in Rust so the fully general form probably
isn't possible as a syntax extension yet, although a limited version is).



--
Simon Sapin
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-07 Thread Huon Wilson

On 07/12/13 20:55, Simon Sapin wrote:

On 07/12/2013 01:14, Huon Wilson wrote:

I personally think a better solution is something like Haskell's do
notation[1], where you can chain several computations that return
Option.. such that if any intermediate one returns None, the later
ones are not evaluated and the whole expression returns None, which
saves having to call .get()/.unwrap()/.expect() a lot.


We have that, it’s Option’s .and_then() method.



This can work for types like Result too (in fact, the Haskell
implementation of `do` is sugar around some monad functions, so any
monad can be used there; we currently don't have the power to express
the monad typeclass/trait in Rust so the fully general form probably
isn't possible as a syntax extension yet, although a limited version 
is).





Yes, that's what my syntax extension[1] (to which Ziad alludes) 
desugared to (well, the former name, .chain).


However, even something simple like `foo.and_then(|x| bar.and_then(|y| 
baz.map(|z| x + y + z)))` is significantly worse than


do
x - foo
y - bar
z - baz
return $ x + y + z

as it is in Haskell. And more complicated examples with additional 
within the closures are significantly worse for the .and_then form 
(leading to pyramids of doom, and Rust already has enough of those).



Huon

[1]: https://mail.mozilla.org/pipermail/rust-dev/2013-May/004182.html
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-07 Thread spir

On 12/07/2013 10:53 AM, Simon Sapin wrote:

On 07/12/2013 01:07, spir wrote:

Maybe it's only me, but this not at at all clear to my eyes. My imagined soluton
(for a totally different lang) was something like this, on the caller side:

ucodes = s.utf8_decode()!// source should be correct, error on failure
  ucodes = s.utf8_decode()?// logical failure expected, return None or
whatnot



This is interesting, but I’d like to discuss what to do in this particular
language, Rust that is trying to go to 1.0 and will probably not accept such
syntax change :)



You are right, indeed! ;-)
But the issue exists anyway... dunno about solution. In fact we'd ned to invert 
the logic: instead of:

x = foo()   // Option element wrapping possible result
x = foo().unwrap()  // bare result
think:
x = foo().option()  // Option element wrapping possible result
x = foo().direct()  // bare result
or even
x = foo()   // bare result

Denis
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-07 Thread spir

On 12/07/2013 02:08 AM, Jordi Boggiano wrote:

On Sat, Dec 7, 2013 at 2:01 AM, spir denis.s...@gmail.com wrote:

On 12/07/2013 01:12 AM, Gaetan wrote:


I am in favor of two version of the api: from_str which has already done
the unwrap, and a from_str_safe for instance that returns a Result or
option.


This provides the important semantic information (that I've evoked at the
end end of a long earlier reply in this thread) of whether func failure is
expected and belongs to the logic of the present app and we must deal with
it, or not.

But I'm still shared on this topic for finding it also annoying, like Simon,
to have to duplicate whole catogories of such funcs (of which we cannot know
in advance whther they'll fail or not), if only the interface as apparently
proposed by Gaëtan.


Syntax sugar like this would be nice:

let str = std::str::from_utf8(Parse this optimistically, and fail otherwise);
// str is a string or the task fails

vs.

let opt_str = std::str::from_utf?(Parse this if valid); // note the
question mark
if opt_str.is_some() {  }


That's it! This makes it clear whenever the anomalous case nevertheless belongs 
to the present application's logic (hopefully rare).




Problem is, this sounds scary to implement at the compiler level, if
it's possible at all :) I am just throwing it out there for others to
judge.


Yes. Requires certainly a bit of machinary, even if thought so from the 
beginning.

But optional tasks exist, semantically, whether the language acknowledges them 
or not. And an Option type only solves half of the issues: namely the ones of 
functions properly speaking (which compute a value); what about actions (which 
perform an effect)? How can Option help the caller know, without failing 
(halting the program on error), whether one has been unable to perform its task? 
How can one know whether this data structure was properly updated, this visual 
object moved, this msg given to the user, this file extended, renamed, deleted...?


There are also, semantically, optional data in function def input and type 
defs... very annoying in a statically typed language ;-)


Denis
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-07 Thread Devin Jeanpierre
On Sat, Dec 7, 2013 at 3:33 AM, spir denis.s...@gmail.com wrote:
 But the issue exists anyway... dunno about solution. In fact we'd ned to
 invert the logic: instead of:
 x = foo()   // Option element wrapping possible result
 x = foo().unwrap()  // bare result
 think:
 x = foo().option()  // Option element wrapping possible result
 x = foo().direct()  // bare result

In what way is this better? Seems to me it's a basically functionless
layer of abstraction, and things that don't always have a usable
result should always return option, and if you want them to fail, you
can request failure via .unwrap(). If this is too verbose, then we
should make it less verbose, e.g. `x = *foo()` or something.

Or we can keep the status quo, which seems fine to me. I'm not really
picky about verbosity.

-- Devin
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-07 Thread Gaetan
What do you think about implicit unwrap? I don't know if this could be done
but I find it pretty elegant.

It's a design choice. For me all API should follow the same pattern, not
some returning bare result without failure case, or return a boolean and
modify the content of a pointer, or use Result/Option.

Most of function look like thing
- function definition
- check inputs are correct
- process with inputs
- return a value

Most of std/extra methods currently look like:
1 function def
2 ... .unwrap()...unwrap()
3 continue to unwrap(), unwrap()
4 return Ok(...) or Err(..) or return Option

while unwrap in part 2 may have sense (check if inputs are correct), they
don't have in the third part of the fn.

What I really advise is to go to a solution where the developer will avoid
each time to call unwrap/get, without checking for the return state because
it cost too much. When you call a system api you check for the result
because it has great chance to fail, but when you know what you have in
input, you call unwrap() without taking care of the failure cases, and if a
failure occurs, you can expect things to be in suffisant bad shape to let
the task completely fails.

Maybe split the methods into two categories: API calls that may fails and
return a Result, and obvious convert methods that has no sens to fails once
the input has been properly check, so doesn't use Result.

But at the end of this discussion, I also strongly advise to write the
solution down in a reference page on the wiki, having the current state of
the art for this matter is extremely important, because the source code
has different design choices, with this page everyone will know what is the
current best pratice for such function calls.

PS: I really like the ? solution, where func?() returns a Result and
func() return the bare result, I find it in the same spirit than fmt!, that
makes the language special but in a sexy way :)


-
Gaetan



2013/12/7 spir denis.s...@gmail.com

 On 12/07/2013 10:53 AM, Simon Sapin wrote:

 On 07/12/2013 01:07, spir wrote:

 Maybe it's only me, but this not at at all clear to my eyes. My imagined
 soluton
 (for a totally different lang) was something like this, on the caller
 side:

 ucodes = s.utf8_decode()!// source should be correct, error on
 failure
   ucodes = s.utf8_decode()?// logical failure expected, return
 None or
 whatnot



 This is interesting, but I’d like to discuss what to do in this particular
 language, Rust that is trying to go to 1.0 and will probably not accept
 such
 syntax change :)



 You are right, indeed! ;-)
 But the issue exists anyway... dunno about solution. In fact we'd ned to
 invert the logic: instead of:
 x = foo()   // Option element wrapping possible result
 x = foo().unwrap()  // bare result
 think:
 x = foo().option()  // Option element wrapping possible result
 x = foo().direct()  // bare result
 or even
 x = foo()   // bare result

 Denis

 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev

___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-07 Thread spir

On 12/07/2013 12:57 PM, Devin Jeanpierre wrote:

On Sat, Dec 7, 2013 at 3:33 AM, spir denis.s...@gmail.com wrote:

But the issue exists anyway... dunno about solution. In fact we'd ned to
invert the logic: instead of:
 x = foo()   // Option element wrapping possible result
 x = foo().unwrap()  // bare result
think:
 x = foo().option()  // Option element wrapping possible result
 x = foo().direct()  // bare result


In what way is this better? Seems to me it's a basically functionless
layer of abstraction, and things that don't always have a usable
result should always return option, and if you want them to fail, you
can request failure via .unwrap(). If this is too verbose, then we
should make it less verbose, e.g. `x = *foo()` or something.

Or we can keep the status quo, which seems fine to me. I'm not really
picky about verbosity.


Possibly it's clear for you if you are used to the Option workaround, from other 
languages (I have been, in fact, from Ocaml). But with this solution the code 
does not say what it means (lol!), not to speak of idioms repeted everywhere in 
source as evoked by Gaetan (and similar to Java, in fact (lol bis!)). However, 
in my view, this is not a question of verbosity, but of having source code match 
(sic!) the semantics, what we actually mean.


A solution would be to have such functions return either a bare result, or an 
Option wrapping a possible result, depending on how they are called (instead of 
'?', there may be a bool param, why not?). But not a functional either/or, this 
would doubly wrap the result! Instead really either one or the other. Indeed, 
this is not possible in standard in a statically typed language, reason for 
other solutions, such as one evoked in a previous mail: have an 'anomaly' flag 
somewhere, possibly a bare pointer for error data, and minimal syntactic 
support. In fact, simple error management (I don't mean exception handling) may 
require being taken into account in language design righ from the start, even 
more than testing  debugging, for instance; but all 3 of those 
meta-programming dimensions are related anyway.


Denis
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-07 Thread Gábor Lehel
I agree with this proposal. I also strongly agree with spir that we should
distinguish programmer errors from legitimate result possibilities. A
function should only fail directly if, were it to return a `None` or `Err`,
the only reasonable the thing caller could do would be to fail itself.

Somewhat formally, a function has a domain and a codomain, i.o.w. the
possible input and output values which make sense. If the type used for the
domain is too big, and allows values which don't make sense in the
context of the function, then this opens up the possibility that the
programmer might mess up and nonetheless pass in one of those values. In
this case the right thing is for the function to fail at runtime: there's
not much else it could do. (This is the null argument /
NullPointerException situation in many other languages.)

The converse case is if the codomain is too small, and doesn't provide a
way to represent all of the possible output values. For example, a search
function might not have a way to say not found. In this case the function
might also want to fail. But in Rust's type system it's much, much, much
easier to make types bigger than it is to make them smaller, so there's no
excuse not to do so. This function should just return an Option.

Of course, it's not always black and white, and what makes sense can
depend on the situation. Sometimes if the container we pass to the search
function doesn't contain the value we're searching for, then it's a bug.
The programmer can always signal this by just calling unwrap() (which I
agree should have a better name, if we can find one) or expect(). But I
think it's also reasonable to add convenience functions if this would be
the case often enough to make them worthwhile. But they should be clearly
presented as added convenience functions, which fail in [these cases] and
not as the default option.

Haskell has a bunch of partial functions which do their equivalent of
failing in their Prelude, such as `head :: [a] - a`, and they've been
regretting it ever since. IMHO, let's try to keep our functions total
whenever we possibly can.


On Fri, Dec 6, 2013 at 9:41 PM, Simon Sapin simon.sa...@exyr.org wrote:

 We have some functions and methods such as [std::str::from_utf8](http://
 static.rust-lang.org/doc/master/std/str/fn.from_utf8.html) that may
 succeed and give a result, or fail when the input is invalid.

 1. Sometimes we assume the input is valid and don’t want to deal with the
 error case. Task failure works nicely.

 2. Sometimes we do want to do something different on invalid input, so
 returning an `OptionT` works best.

 And so we end up with both `from_utf8` and `from_utf8`. This particular
 case is worse because we also have `from_utf8_owned` and
 `from_utf8_owned_opt`, to cover everything.

 Multiplying names like this is just not good design. I’d like to reduce
 this pattern.

 Getting behavior 1. when you have 2. is easy: just call `.unwrap()` on the
 Option. I think we should rename every `foo_opt()` function or method to
 just `foo`, remove the old `foo()` behavior, and tell people (through
 documentation) to use `foo().unwrap()` if they want it back?

 The downsides are that unwrap is more verbose and gives less helpful error
 messages on task failure. But I think it’s worth it.

 What do you think?

 (PS: I’m guilty of making this worse in #10828, but I’d like to discuss
 this before sending pull requests with invasive API changes.)

 --
 Simon Sapin
 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev




-- 
Your ship was destroyed in a monadic eruption.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-06 Thread Simon Sapin
We have some functions and methods such as 
[std::str::from_utf8](http://static.rust-lang.org/doc/master/std/str/fn.from_utf8.html) 
that may succeed and give a result, or fail when the input is invalid.


1. Sometimes we assume the input is valid and don’t want to deal with 
the error case. Task failure works nicely.


2. Sometimes we do want to do something different on invalid input, so 
returning an `OptionT` works best.


And so we end up with both `from_utf8` and `from_utf8`. This particular 
case is worse because we also have `from_utf8_owned` and 
`from_utf8_owned_opt`, to cover everything.


Multiplying names like this is just not good design. I’d like to reduce 
this pattern.


Getting behavior 1. when you have 2. is easy: just call `.unwrap()` on 
the Option. I think we should rename every `foo_opt()` function or 
method to just `foo`, remove the old `foo()` behavior, and tell people 
(through documentation) to use `foo().unwrap()` if they want it back?


The downsides are that unwrap is more verbose and gives less helpful 
error messages on task failure. But I think it’s worth it.


What do you think?

(PS: I’m guilty of making this worse in #10828, but I’d like to discuss 
this before sending pull requests with invasive API changes.)


--
Simon Sapin
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-06 Thread Corey Richardson
I'm in favor of this but it makes things less pretty. Is the choice
really between pretty and fast?

On Fri, Dec 6, 2013 at 3:41 PM, Simon Sapin simon.sa...@exyr.org wrote:
 We have some functions and methods such as
 [std::str::from_utf8](http://static.rust-lang.org/doc/master/std/str/fn.from_utf8.html)
 that may succeed and give a result, or fail when the input is invalid.

 1. Sometimes we assume the input is valid and don’t want to deal with the
 error case. Task failure works nicely.

 2. Sometimes we do want to do something different on invalid input, so
 returning an `OptionT` works best.

 And so we end up with both `from_utf8` and `from_utf8`. This particular case
 is worse because we also have `from_utf8_owned` and `from_utf8_owned_opt`,
 to cover everything.

 Multiplying names like this is just not good design. I’d like to reduce this
 pattern.

 Getting behavior 1. when you have 2. is easy: just call `.unwrap()` on the
 Option. I think we should rename every `foo_opt()` function or method to
 just `foo`, remove the old `foo()` behavior, and tell people (through
 documentation) to use `foo().unwrap()` if they want it back?

 The downsides are that unwrap is more verbose and gives less helpful error
 messages on task failure. But I think it’s worth it.

 What do you think?

 (PS: I’m guilty of making this worse in #10828, but I’d like to discuss this
 before sending pull requests with invasive API changes.)

 --
 Simon Sapin
 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-06 Thread Daniel Micay
On Fri, Dec 6, 2013 at 3:41 PM, Simon Sapin simon.sa...@exyr.org wrote:
 We have some functions and methods such as
 [std::str::from_utf8](http://static.rust-lang.org/doc/master/std/str/fn.from_utf8.html)
 that may succeed and give a result, or fail when the input is invalid.

 1. Sometimes we assume the input is valid and don’t want to deal with the
 error case. Task failure works nicely.

 2. Sometimes we do want to do something different on invalid input, so
 returning an `OptionT` works best.

 And so we end up with both `from_utf8` and `from_utf8`. This particular case
 is worse because we also have `from_utf8_owned` and `from_utf8_owned_opt`,
 to cover everything.

 Multiplying names like this is just not good design. I’d like to reduce this
 pattern.

 Getting behavior 1. when you have 2. is easy: just call `.unwrap()` on the
 Option. I think we should rename every `foo_opt()` function or method to
 just `foo`, remove the old `foo()` behavior, and tell people (through
 documentation) to use `foo().unwrap()` if they want it back?

 The downsides are that unwrap is more verbose and gives less helpful error
 messages on task failure. But I think it’s worth it.

 What do you think?

 (PS: I’m guilty of making this worse in #10828, but I’d like to discuss this
 before sending pull requests with invasive API changes.)

 --
 Simon Sapin

A stack trace already tells you where the error came from so I don't
think it's an important consideration. Rust can provide stack traces
on failure by default if that's desired.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-06 Thread Brian Anderson

On 12/06/2013 12:41 PM, Simon Sapin wrote:
We have some functions and methods such as 
[std::str::from_utf8](http://static.rust-lang.org/doc/master/std/str/fn.from_utf8.html) 
that may succeed and give a result, or fail when the input is invalid.


1. Sometimes we assume the input is valid and don’t want to deal with 
the error case. Task failure works nicely.


2. Sometimes we do want to do something different on invalid input, so 
returning an `OptionT` works best.


And so we end up with both `from_utf8` and `from_utf8`. This 
particular case is worse because we also have `from_utf8_owned` and 
`from_utf8_owned_opt`, to cover everything.


Multiplying names like this is just not good design. I’d like to 
reduce this pattern.


Getting behavior 1. when you have 2. is easy: just call `.unwrap()` on 
the Option. I think we should rename every `foo_opt()` function or 
method to just `foo`, remove the old `foo()` behavior, and tell people 
(through documentation) to use `foo().unwrap()` if they want it back?


The downsides are that unwrap is more verbose and gives less helpful 
error messages on task failure. But I think it’s worth it.


What do you think?

(PS: I’m guilty of making this worse in #10828, but I’d like to 
discuss this before sending pull requests with invasive API changes.)




I agree in this case (and probably a lot of cases), especially since 
this is a relatively uncommon operation and since (I think) we're 
prefering 'get' to 'unwrap' and that's even shorter.


There are some cases where I think failure is the right option by 
default though; in particular I was worried you were going to bring up 
the 'send' and 'recv' methods on channels which fail when disconnected. 
In this case I think it won't be common to handle the failure since it 
indicates some logic error, and these are very common operations.


___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-06 Thread Simon Sapin

On 06/12/2013 20:48, Corey Richardson wrote:

I'm in favor of this but it makes things less pretty. Is the choice
really between pretty and fast?


I don’t think this is about speed. My concern is that having two 
almost-identical names for functions that do almost the same thing is 
not a good design, and should be avoided if possible.


--
Simon Sapin
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-06 Thread Simon Sapin

On 06/12/2013 20:55, Léo Testard wrote:

Hi,

Just a suggestion, don't know what it's worth...

For the not helpful error message thing, couldn't we extend the
option API, to be able to specify at the creation of a None value
the error string that will be displayed if one calls unwrap() on this
value ? This may be useful in several situations.


That would require making the memory representation of every Option 
bigger. Just for the (hopefully) uncommon case of task failure, it’s not 
worth the cost in my opinion.


We could instead have .unwrap() that take an error message, but that 
leaves the responsibility to the user of the API.


--
Simon Sapin
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-06 Thread Eric Reed
FYI, there's already a method on Option that is unwrap() with an error
message: expect().

Personally, I prefer making functions that don't fail and use Option or
Result and then composing them with functions that fail for certain
outputs, but I think I'm in the minority there.


On Fri, Dec 6, 2013 at 1:45 PM, Simon Sapin simon.sa...@exyr.org wrote:

 On 06/12/2013 20:55, Léo Testard wrote:

 Hi,

 Just a suggestion, don't know what it's worth...

 For the not helpful error message thing, couldn't we extend the
 option API, to be able to specify at the creation of a None value
 the error string that will be displayed if one calls unwrap() on this
 value ? This may be useful in several situations.


 That would require making the memory representation of every Option
 bigger. Just for the (hopefully) uncommon case of task failure, it’s not
 worth the cost in my opinion.

 We could instead have .unwrap() that take an error message, but that
 leaves the responsibility to the user of the API.


 --
 Simon Sapin
 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev

___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-06 Thread Simon Sapin

On 06/12/2013 21:44, Brian Anderson wrote:

I agree in this case (and probably a lot of cases), especially since
this is a relatively uncommon operation and since (I think) we're
prefering 'get' to 'unwrap' and that's even shorter.

There are some cases where I think failure is the right option by
default though; in particular I was worried you were going to bring up
the 'send' and 'recv' methods on channels which fail when disconnected.
In this case I think it won't be common to handle the failure since it
indicates some logic error, and these are very common operations.



Maybe this should be a case-by-case decision, but send/try_send and 
recv/try_recv have the same issue as from_utf8/from_utf8_opt of two 
slightly different names for almost the same thing.


--
Simon Sapin
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-06 Thread Simon Sapin

On 06/12/2013 21:50, Eric Reed wrote:

Personally, I prefer making functions that don't fail and use Option or
Result and then composing them with functions that fail for certain
outputs, but I think I'm in the minority there.


Yes, this is what I’m suggesting.

--
Simon Sapin
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-06 Thread Palmer Cox
Why not use Result instead of Option for these types of things? Result is
already defined to be able to return error codes using Err. The only way to
indicate an error when returning an Option is to return None which doesn't
allow for that. Also, IMO, None doesn't necessarily mean error to me.
Lets say we have a function defined as:

fn do_something(value: Option~str);

It seems like it would be much to easy to accidentally write something
like: do_something(str::from_utf8(...)) which might result in the error
being hidden since do_something might not consider None to be an error
input.

-Palmer Cox



On Fri, Dec 6, 2013 at 4:52 PM, Simon Sapin simon.sa...@exyr.org wrote:

 On 06/12/2013 21:50, Eric Reed wrote:

 Personally, I prefer making functions that don't fail and use Option or
 Result and then composing them with functions that fail for certain
 outputs, but I think I'm in the minority there.


 Yes, this is what I’m suggesting.


 --
 Simon Sapin
 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev

___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-06 Thread Gaetan
I also find the repeatition of unwrap all over the code being quite nasty

Most of the time the result is just unwrapped without taking into account
the error case, so i think the usage of Option or Result useless.

I think a good solution exits and can make the code more maintainable, and
easier to read. There should not have all these unwrap (or get) call for
code we know it cannot fails, because the necessary check has been done
earlier.

I am in favor of two version of the api: from_str which has already done
the unwrap, and a from_str_safe for instance that returns a Result or
option.

Or perhaps allow the propagation of Option/Result.
Le 7 déc. 2013 01:03, Daniel Micay danielmi...@gmail.com a écrit :

 On Fri, Dec 6, 2013 at 7:00 PM, Palmer Cox palmer...@gmail.com wrote:
  Why not use Result instead of Option for these types of things? Result is
  already defined to be able to return error codes using Err. The only way
 to
  indicate an error when returning an Option is to return None which
 doesn't
  allow for that. Also, IMO, None doesn't necessarily mean error to me.
 Lets
  say we have a function defined as:
 
  fn do_something(value: Option~str);
 
  It seems like it would be much to easy to accidentally write something
 like:
  do_something(str::from_utf8(...)) which might result in the error being
  hidden since do_something might not consider None to be an error input.
 
  -Palmer Cox

 If there's only one reason it could fail, then `Option` is the
 idiomatic way to report the error case. It's exactly what `Option` is
 used for. A stack trace can report where the error occurred if you
 decide to ignore the error case and use `unwrap` (or `get`, if it's
 renamed).
 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev

___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-06 Thread Gaetan
Isnt a way for Option to unwrap implicitely when check on error state is
not done ? That would make the code less verbose but still allow the dev to
check for error if want?
Le 7 déc. 2013 01:12, Gaetan gae...@xeberon.net a écrit :

 I also find the repeatition of unwrap all over the code being quite nasty

 Most of the time the result is just unwrapped without taking into account
 the error case, so i think the usage of Option or Result useless.

 I think a good solution exits and can make the code more maintainable, and
 easier to read. There should not have all these unwrap (or get) call for
 code we know it cannot fails, because the necessary check has been done
 earlier.

 I am in favor of two version of the api: from_str which has already done
 the unwrap, and a from_str_safe for instance that returns a Result or
 option.

 Or perhaps allow the propagation of Option/Result.
 Le 7 déc. 2013 01:03, Daniel Micay danielmi...@gmail.com a écrit :

 On Fri, Dec 6, 2013 at 7:00 PM, Palmer Cox palmer...@gmail.com wrote:
  Why not use Result instead of Option for these types of things? Result
 is
  already defined to be able to return error codes using Err. The only
 way to
  indicate an error when returning an Option is to return None which
 doesn't
  allow for that. Also, IMO, None doesn't necessarily mean error to me.
 Lets
  say we have a function defined as:
 
  fn do_something(value: Option~str);
 
  It seems like it would be much to easy to accidentally write something
 like:
  do_something(str::from_utf8(...)) which might result in the error being
  hidden since do_something might not consider None to be an error input.
 
  -Palmer Cox

 If there's only one reason it could fail, then `Option` is the
 idiomatic way to report the error case. It's exactly what `Option` is
 used for. A stack trace can report where the error occurred if you
 decide to ignore the error case and use `unwrap` (or `get`, if it's
 renamed).
 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev


___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-06 Thread Simon Sapin

On 07/12/2013 00:12, Gaetan wrote:

I am in favor of two version of the api: from_str which has already done
the unwrap, and a from_str_safe for instance that returns a Result or
option.


This is what we have now. (Eg. from_utf8() and from_utf8_opt())

The point of my initial email was to argue against this. I think we 
should try to avoid doubling the amount of API.




Or perhaps allow the propagation of Option/Result.


This is why we have methods like .map() and .and_then()

--
Simon Sapin
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-06 Thread spir

On 12/06/2013 09:41 PM, Simon Sapin wrote:

We have some functions and methods such as
[std::str::from_utf8](http://static.rust-lang.org/doc/master/std/str/fn.from_utf8.html)
that may succeed and give a result, or fail when the input is invalid.

1. Sometimes we assume the input is valid and don’t want to deal with the error
case. Task failure works nicely.

2. Sometimes we do want to do something different on invalid input, so returning
an `OptionT` works best.

And so we end up with both `from_utf8` and `from_utf8`. This particular case is
worse because we also have `from_utf8_owned` and `from_utf8_owned_opt`, to cover
everything.

Multiplying names like this is just not good design. I’d like to reduce this
pattern.

Getting behavior 1. when you have 2. is easy: just call `.unwrap()` on the
Option. I think we should rename every `foo_opt()` function or method to just
`foo`, remove the old `foo()` behavior, and tell people (through documentation)
to use `foo().unwrap()` if they want it back?

The downsides are that unwrap is more verbose and gives less helpful error
messages on task failure. But I think it’s worth it.

What do you think?

(PS: I’m guilty of making this worse in #10828, but I’d like to discuss this
before sending pull requests with invasive API changes.)


[A bit long, sorry, this is a topic about which i have thought for a while.]

There may be a more complicated general pattern, of all kinds of functions that 
may not be able to perform their nominal task, due to invalid input, but the 
client cannot know whether the input is valid without more or less reproducing 
said task. Checking utf8 validity is about the same job as decoding, for 
instance, to reuse your example.


Compare with a function computing the average value of a collection of numbers 
(or the sum, product, std-dev, etc...) which is passed an empty collection: here 
the client can know, thus:
1. if this abnormal case does not belong to the app's logic, the client should 
just call the func stupidly so that the func failure is a signal of logical 
error on the app side
2. if instead this case belongs to the app's logic, the client should first 
check, and never call the func in this special case
Thus, despite very possible failure, there should here be only one version of 
the func (no *_opt), one that stupidly fails, with a stupid error msg.


Back to the cases where the client cannot know before calling. To this category 
belong a whole series of search/find functions, and many dealing with the file 
system, user input, input in general. In the latter case, a func's input is in 
fact not (all) provided by the client. But there is the same pattern of 
anomalous cases which may, or not, belong to the app logic (1. or 2. above): is 
it correct (if special or exceptional) that such file does not exist, or such 
collection does not hold the searched item? Meaning, should I deal with such 
cases? If not, if such a case does not belong to the application logic, again I 
should stupidly call a func that stupidly fails with a stupid error msg, so I am 
told, simply and early, of my logical errors. These are true errors (not 
so-called exceptions), and the failure is a symptom or signal, a good thing (if, 
indeed, what you want is making good software). I *want* it; and want it so!


I'm in favor of simple funcs doing simple tasks simply, and just failing in 
anomalous cases, for these reasons. [1]


Remains the situation combined of such funcs, of which the client cannot know 
whether they will be able to perform their task, and of abnormal cases belonging 
to the logic of the app (there are also whole categories of maintenance and 
safety modes here). For such situations, it looks somewhat logical to have 2 
versions, I guess. Playing a bit with words:
1. when I ask to _find_ something, I take it for granted the thing is somewhere 
there, and expect a location in return
2. when I ask to _search_ something, I do not take anything for granted, and 
expect in return _either_ not there! or a location
This duality applies both to the so-called real world (despite blur natural 
language word meanings) and software worlds, and extends to all cases, it seems. 
We can certainly find a way, using Option or another mean, to combine both 
categories of situations (1. or 2.) using a single tool, but this should be very 
well done, and ensure that:
* In cases of category 1., developers are warned about their errors exactly as 
if they had called a stupidly failing func.
* At the semantic (conceptual) level, the duality of categories remains somehow 
preserved, including in source code.
About the latter, in particular it should be obvious in code, without knowledge 
of language arcanes or weird idioms, that (or whether) the caller expects a 
success unconditionally -- because (and in other words that) the anomalous case 
just does not belong to this app; this is critical information to the reader. 
How to do that right?


PS: I take the 

Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-06 Thread Simon Sapin

On 07/12/2013 00:49, spir wrote:

About the latter, in particular it should be obvious in code, without knowledge
of language arcanes or weird idioms, that (or whether) the caller expects a
success unconditionally -- because (and in other words that) the anomalous case
just does not belong to this app; this is critical information to the reader.
How to do that right?


If my proposal is accepted (returning Option is favored), then calling 
.unwrap() is the way to express that success is expected. unwrap() 
causes task failure when called with None.


--
Simon Sapin
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-06 Thread spir

On 12/07/2013 01:12 AM, Gaetan wrote:

I am in favor of two version of the api: from_str which has already done
the unwrap, and a from_str_safe for instance that returns a Result or
option.


This provides the important semantic information (that I've evoked at the end 
end of a long earlier reply in this thread) of whether func failure is expected 
and belongs to the logic of the present app and we must deal with it, or not.


But I'm still shared on this topic for finding it also annoying, like Simon, to 
have to duplicate whole catogories of such funcs (of which we cannot know in 
advance whther they'll fail or not), if only the interface as apparently 
proposed by Gaëtan.


Denis
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-06 Thread spir

On 12/07/2013 01:55 AM, Simon Sapin wrote:

On 07/12/2013 00:49, spir wrote:

About the latter, in particular it should be obvious in code, without knowledge
of language arcanes or weird idioms, that (or whether) the caller expects a
success unconditionally -- because (and in other words that) the anomalous case
just does not belong to this app; this is critical information to the reader.
How to do that right?


If my proposal is accepted (returning Option is favored), then calling .unwrap()
is the way to express that success is expected. unwrap() causes task failure
when called with None.


Maybe it's only me, but this not at at all clear to my eyes. My imagined soluton 
(for a totally different lang) was something like this, on the caller side:


ucodes = s.utf8_decode()!   // source should be correct, error on 
failure
ucodes = s.utf8_decode()?	// logical failure expected, return None or 
whatnot


(But maybe _this_ is obscure to your eyes?)

Denis
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-06 Thread Jordi Boggiano
On Sat, Dec 7, 2013 at 2:01 AM, spir denis.s...@gmail.com wrote:
 On 12/07/2013 01:12 AM, Gaetan wrote:

 I am in favor of two version of the api: from_str which has already done
 the unwrap, and a from_str_safe for instance that returns a Result or
 option.

 This provides the important semantic information (that I've evoked at the
 end end of a long earlier reply in this thread) of whether func failure is
 expected and belongs to the logic of the present app and we must deal with
 it, or not.

 But I'm still shared on this topic for finding it also annoying, like Simon,
 to have to duplicate whole catogories of such funcs (of which we cannot know
 in advance whther they'll fail or not), if only the interface as apparently
 proposed by Gaëtan.

Syntax sugar like this would be nice:

let str = std::str::from_utf8(Parse this optimistically, and fail otherwise);
// str is a string or the task fails

vs.

let opt_str = std::str::from_utf?(Parse this if valid); // note the
question mark
if opt_str.is_some() {  }

Problem is, this sounds scary to implement at the compiler level, if
it's possible at all :) I am just throwing it out there for others to
judge.

Cheers

-- 
Jordi Boggiano
@seldaek - http://nelm.io/jordi
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-06 Thread Huon Wilson

On 07/12/13 12:08, Jordi Boggiano wrote:

On Sat, Dec 7, 2013 at 2:01 AM, spir denis.s...@gmail.com wrote:

On 12/07/2013 01:12 AM, Gaetan wrote:

I am in favor of two version of the api: from_str which has already done
the unwrap, and a from_str_safe for instance that returns a Result or
option.

This provides the important semantic information (that I've evoked at the
end end of a long earlier reply in this thread) of whether func failure is
expected and belongs to the logic of the present app and we must deal with
it, or not.

But I'm still shared on this topic for finding it also annoying, like Simon,
to have to duplicate whole catogories of such funcs (of which we cannot know
in advance whther they'll fail or not), if only the interface as apparently
proposed by Gaëtan.

Syntax sugar like this would be nice:

let str = std::str::from_utf8(Parse this optimistically, and fail otherwise);
// str is a string or the task fails

vs.

let opt_str = std::str::from_utf?(Parse this if valid); // note the
question mark
if opt_str.is_some() {  }

Problem is, this sounds scary to implement at the compiler level, if
it's possible at all :) I am just throwing it out there for others to
judge.

Cheers



I personally think a better solution is something like Haskell's do 
notation[1], where you can chain several computations that return 
Option.. such that if any intermediate one returns None, the later 
ones are not evaluated and the whole expression returns None, which 
saves having to call .get()/.unwrap()/.expect() a lot.


This can work for types like Result too (in fact, the Haskell 
implementation of `do` is sugar around some monad functions, so any 
monad can be used there; we currently don't have the power to express 
the monad typeclass/trait in Rust so the fully general form probably 
isn't possible as a syntax extension yet, although a limited version is).



Huon

[1]: http://en.wikibooks.org/wiki/Haskell/do_Notation

___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-06 Thread Jordi Boggiano
On Sat, Dec 7, 2013 at 2:07 AM, spir denis.s...@gmail.com wrote:
 Maybe it's only me, but this not at at all clear to my eyes. My imagined
 soluton (for a totally different lang) was something like this, on the
 caller side:

 ucodes = s.utf8_decode()!   // source should be correct, error
 on failure
 ucodes = s.utf8_decode()?   // logical failure expected, return
 None or whatnot

 (But maybe _this_ is obscure to your eyes?)

Looks like our mails had a race condition on this one, but
highlighting the cases where we expect a perfect world (i.e. !) is
probably better.

However, if you just call the method without anything it would be the
same as calling it with ? suffix as far as I understand, so I'm not
sure what the point is of keeping that one.

Cheers

-- 
Jordi Boggiano
@seldaek - http://nelm.io/jordi
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-06 Thread Liigo Zhuang
Is do-notation in Haskell similar as: try{ block } ?


2013/12/7 Huon Wilson dbau...@gmail.com

 On 07/12/13 12:08, Jordi Boggiano wrote:

 On Sat, Dec 7, 2013 at 2:01 AM, spir denis.s...@gmail.com wrote:

 On 12/07/2013 01:12 AM, Gaetan wrote:

 I am in favor of two version of the api: from_str which has already done
 the unwrap, and a from_str_safe for instance that returns a Result or
 option.

 This provides the important semantic information (that I've evoked at the
 end end of a long earlier reply in this thread) of whether func failure
 is
 expected and belongs to the logic of the present app and we must deal
 with
 it, or not.

 But I'm still shared on this topic for finding it also annoying, like
 Simon,
 to have to duplicate whole catogories of such funcs (of which we cannot
 know
 in advance whther they'll fail or not), if only the interface as
 apparently
 proposed by Gaëtan.

 Syntax sugar like this would be nice:

 let str = std::str::from_utf8(Parse this optimistically, and fail
 otherwise);
 // str is a string or the task fails

 vs.

 let opt_str = std::str::from_utf?(Parse this if valid); // note the
 question mark
 if opt_str.is_some() {  }

 Problem is, this sounds scary to implement at the compiler level, if
 it's possible at all :) I am just throwing it out there for others to
 judge.

 Cheers


 I personally think a better solution is something like Haskell's do
 notation[1], where you can chain several computations that return
 Option.. such that if any intermediate one returns None, the later ones
 are not evaluated and the whole expression returns None, which saves having
 to call .get()/.unwrap()/.expect() a lot.

 This can work for types like Result too (in fact, the Haskell
 implementation of `do` is sugar around some monad functions, so any monad
 can be used there; we currently don't have the power to express the monad
 typeclass/trait in Rust so the fully general form probably isn't possible
 as a syntax extension yet, although a limited version is).


 Huon

 [1]: http://en.wikibooks.org/wiki/Haskell/do_Notation


 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev




-- 
by *Liigo*, http://blog.csdn.net/liigo/
Google+  https://plus.google.com/105597640837742873343/
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-06 Thread Ziad Hatahet
I posted a question on the mailing list concerning this back in May:
https://mail.mozilla.org/pipermail/rust-dev/2013-May/004176.html

There were a couple of responses which implemented this in a macro. It
would be nice if it were at the language level though.


--
Ziad


On Fri, Dec 6, 2013 at 5:14 PM, Huon Wilson dbau...@gmail.com wrote:

 On 07/12/13 12:08, Jordi Boggiano wrote:

 On Sat, Dec 7, 2013 at 2:01 AM, spir denis.s...@gmail.com wrote:

 On 12/07/2013 01:12 AM, Gaetan wrote:

 I am in favor of two version of the api: from_str which has already done
 the unwrap, and a from_str_safe for instance that returns a Result or
 option.

 This provides the important semantic information (that I've evoked at the
 end end of a long earlier reply in this thread) of whether func failure
 is
 expected and belongs to the logic of the present app and we must deal
 with
 it, or not.

 But I'm still shared on this topic for finding it also annoying, like
 Simon,
 to have to duplicate whole catogories of such funcs (of which we cannot
 know
 in advance whther they'll fail or not), if only the interface as
 apparently
 proposed by Gaëtan.

 Syntax sugar like this would be nice:

 let str = std::str::from_utf8(Parse this optimistically, and fail
 otherwise);
 // str is a string or the task fails

 vs.

 let opt_str = std::str::from_utf?(Parse this if valid); // note the
 question mark
 if opt_str.is_some() {  }

 Problem is, this sounds scary to implement at the compiler level, if
 it's possible at all :) I am just throwing it out there for others to
 judge.

 Cheers


 I personally think a better solution is something like Haskell's do
 notation[1], where you can chain several computations that return
 Option.. such that if any intermediate one returns None, the later ones
 are not evaluated and the whole expression returns None, which saves having
 to call .get()/.unwrap()/.expect() a lot.

 This can work for types like Result too (in fact, the Haskell
 implementation of `do` is sugar around some monad functions, so any monad
 can be used there; we currently don't have the power to express the monad
 typeclass/trait in Rust so the fully general form probably isn't possible
 as a syntax extension yet, although a limited version is).


 Huon

 [1]: http://en.wikibooks.org/wiki/Haskell/do_Notation


 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev

___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-06 Thread Patrick Walton

On 12/6/13 6:46 PM, Niko Matsakis wrote:

I agree. I've personally been moving towards `ResultT, ()` in
preference to `OptionT` when one of the branches reflects an
error. It's worth noting that the compiler could still optimize this
into a pointer-null-pointer representation, though I doubt it does so
now.


IIRC it does.

Patrick

___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-06 Thread Brendan Zabarauskas

On 7 Dec 2013, at 10:47 am, Simon Sapin simon.sa...@exyr.org wrote:

 This is why we have methods like .map() and .and_then()

I like using these higher order functions, but I run into lots of issues with 
moved values because we don’t have once functions. I end up having to use 
matches, which are awfully verbose for simple things. :(

~Brendan
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-06 Thread Oren Ben-Kiki
There was a whole thread about the need for once-stack-closures. They are
really vital for simple programming with higher-order functions such as
these. I'm not optimistic about them being added though :-(


On Sat, Dec 7, 2013 at 8:15 AM, Brendan Zabarauskas bjz...@yahoo.com.auwrote:


 On 7 Dec 2013, at 10:47 am, Simon Sapin simon.sa...@exyr.org wrote:

  This is why we have methods like .map() and .and_then()

 I like using these higher order functions, but I run into lots of issues
 with moved values because we don’t have once functions. I end up having to
 use matches, which are awfully verbose for simple things. :(

 ~Brendan
 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev

___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Let’s avoid having both foo() and foo_opt()

2013-12-06 Thread Palmer Cox
Especially if ResultT, () is optimized into a single word, it seems ideal
to me to get rid of str::from_utf_opt([u8]) - Option~str and just have
str::from_utf([u8]) - Result~str, (). This makes simple programs that
don't care about error handling a little more complicated, of course, since
it forces them to handle the error case. Although, the only extra
complication is .unwrap() so, its not that bad. For more complex programs
that do care about error handling it makes it explicit at the call site how
the error condition should be handled which I think is a big win. Return
code checking is a C idiom, and there is nothing wrong with that style of
error handling. However, the C compiler doesn't do much of anything to
force you to check the return codes which leads to lots of code that fails
to do so. Using a Result, however, forces the caller to do those checks.
Result still supports various chaining functions just like Option to
make that easier. However, you don't have to worry about accidentally
passing a None to a function that takes an Option as an input parameter
with non-error semantics.

Also, I like unwrap() since to me, nothing about get() says: this is an
error handling function that might lead to killing the current task. get()
sounds simple and safe, buts its not if called on an Option.

-Palmer Cox


On Fri, Dec 6, 2013 at 11:14 PM, Patrick Walton pcwal...@mozilla.comwrote:

 On 12/6/13 6:46 PM, Niko Matsakis wrote:

 I agree. I've personally been moving towards `ResultT, ()` in
 preference to `OptionT` when one of the branches reflects an
 error. It's worth noting that the compiler could still optimize this
 into a pointer-null-pointer representation, though I doubt it does so
 now.


 IIRC it does.

 Patrick


 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev

___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev