Hacker News new | past | comments | ask | show | jobs | submit login

The Kotlin compiler can handle chains of potentially().nullable()?.invocations(). Is the Rust early-error returning not a similar case, or am I missing something?



Yeah, Rust does that as well. The issue the author is talking about here is that when you write a closure:

    fn foo(inputs: &[Input]) -> Result<Vec<Output>, Error> {
        inputs
        .iter()
        .map(|input| { input.something_fallible()? })
        .collect()
    }
that ? is an early return from the closure, not foo. The correct way to do this is:

    fn foo(inputs: &[Input]) -> Result<Vec<Output>, Error> {
        inputs
        .iter()
        .map(|input| { input.something_fallible() })
        .collect::<Result<Vec<Output>, Error>>()
    }
ref: https://play.rust-lang.org/?version=stable&mode=debug&editio...


I wonder how come the type must be specified explicitly as "collect::<Result<Vec<Output>, Error>>()" and can't be inferred, given that the function return type is already spelled out as "Result<Vec<Output>, Error>"? Is there a specialisation for collect() for Result<> types that has to be explicitly triggered?


It doesn't have to be specified explicitly in this case, it can be inferred.

https://play.rust-lang.org/?version=stable&mode=debug&editio...

Probably just habit from GP to write out the return type, since collect so often can't be inferred. Or maybe to make it easier to change it to an intermediate value which you use ? with (at which point the type can no longer be inferred).

https://play.rust-lang.org/?version=stable&mode=debug&editio...


Yeah, apologies, that's just habit on my part.


Kotlin and also C# ? operators only “return” from the expression being evaluated. Most documentation says “return” a bit ambiguously but that’s what they mean. AFAIK Rust is the first language to use ? in such a way as to return from a function, and that’s quite different. Kotlin ? can technically be emulated in Rust with an IIFE (immediately invoked function expression) like so:

    // never do this, it’s rude
    let x = (|| potentially().nullable()?.invocations())();
Or with Option::map, and_then and friends:

    // this is the way
    let x = potentially().nullable().map(|y| y.invocations());


That made it click, thanks!


Rust does the same.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: