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

Vadim vadimcn at gmail.com
Tue Jan 7 19:31:16 PST 2014


On Tue, Jan 7, 2014 at 6:39 PM, Nick Cameron <lists at 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 <vadimcn at gmail.com> wrote:
>
>> I can see how '?.' would work when foo() returns a struct, but what about
>> non-struct types, e.g. Option<i32> ?   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 <lists at 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 : Option<T'>
>>> fType(T', f) = T
>>> ------------------------------------
>>> \Gamma e?f : Option<T>
>>>
>>> e?f ~~> match e { Some<e> => Some<e.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.sapin at 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 `Option<T>` 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 at mozilla.org
>>>> https://mail.mozilla.org/listinfo/rust-dev
>>>>
>>>
>>>
>>> _______________________________________________
>>> Rust-dev mailing list
>>> Rust-dev at mozilla.org
>>> https://mail.mozilla.org/listinfo/rust-dev
>>>
>>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20140107/8579ca1a/attachment-0001.html>


More information about the Rust-dev mailing list