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


[rust-dev] See pull request #11129 (was: Re: Let’s avoid having both foo() and foo_opt())

2013-12-23 Thread Simon Sapin

FYI, made a pull request according to this proposal:

https://github.com/mozilla/rust/pull/11129

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


Re: [rust-dev] See pull request #11129 (was: Re: Let’s avoid having both foo() and foo_opt())

2013-12-23 Thread Liigo Zhuang
Code full of .unwrap() is not good smell I think.
在 2013年12月24日 上午4:42,Simon Sapin simon.sa...@exyr.org写道:

 FYI, made a pull request according to this proposal:

 https://github.com/mozilla/rust/pull/11129

 --
 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] See pull request #11129

2013-12-23 Thread Simon Sapin

On 23/12/2013 22:19, Liigo Zhuang wrote:

Code full of .unwrap() is not good smell I think.


I agree, and I wrote in the first email that it is one of the downsides.

But doubling the API (from_utf8 and from_utf8_opt) is also not a good 
smell, so it’s a compromise to find.


--
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] See pull request #11129

2013-12-23 Thread Kevin Ballard
Even with refutable `let`s, I think there's still a good case for having 
`.unwrap()`-style APIs on enums, which is that often you need to unwrap an enum 
inside a larger expression. A refutable `let` only works if you're actually 
using a `let`-binding to begin with.

-Kevin

On Dec 23, 2013, at 1:24 PM, Simon Sapin simon.sa...@exyr.org wrote:

 On 23/12/2013 22:19, Liigo Zhuang wrote:
 Code full of .unwrap() is not good smell I think.
 
 I agree, and I wrote in the first email that it is one of the downsides.
 
 But doubling the API (from_utf8 and from_utf8_opt) is also not a good smell, 
 so it’s a compromise to find.
 
 -- 
 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] See pull request #11129

2013-12-23 Thread Simon Sapin

On 23/12/2013 22:26, Kevin Ballard wrote:

Even with refutable `let`s, I think there's still a good case for
having `.unwrap()`-style APIs on enums, which is that often you need
to unwrap an enum inside a larger expression. A refutable `let` only
works if you're actually using a `let`-binding to begin with.


Please don’t change the subject of (at least this part of) this thread.

This is about having both variations of an API (using task failure or 
returning Option) vs. only the latter (and using unwrap() when task 
failure is desired.) It is not about refutable let vs. unwrap-style methods.


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