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

Vadim vadimcn at gmail.com
Tue Jan 7 16:42:49 PST 2014


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/62b9fc50/attachment.html>


More information about the Rust-dev mailing list