Stream: beginners

Topic: Early return


view this post on Zulip Ben (Feb 03 2025 at 02:27):

Roc doesn't have a return statement yet, correct? Any plans to add? Something like

if expr then
    return Err(MyError)

If I have many checks in a row like that, is there a functional pattern to achieve that elegantly?

If there was a Bool.then function perhaps something like expr |> Bool.then(Err(MyError))?

view this post on Zulip Luke Boswell (Feb 03 2025 at 02:32):

Roc doesn't have a return statement

It does... here's a working example

app [main!] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.19.0/Hj-J_zxz7V9YurCSTFcFdu6cQJie4guzsPMUi5kBYUk.tar.br" }

main! = |_|
    if Bool.true then
        return Err(Exit(1,"This is a test error message"))
    else
        Ok({})

view this post on Zulip Luke Boswell (Feb 03 2025 at 02:32):

$ roc test.roc
This is a test error message

view this post on Zulip Ben (Feb 03 2025 at 02:37):

If I have logic following my if block, I guess I need to assign the result of the if expression? I can't omit the else right? Feels a bit clunky :(

_ = if Bool.true then
        return Err(Exit(1,"This is a test error message"))
    else
        Ok({})
Ok({})

view this post on Zulip Luke Boswell (Feb 03 2025 at 02:43):

If you have a larger example I may be able to help you find a nicer pattern. I was just answering your immediate question of if there is a return.

view this post on Zulip Ben (Feb 03 2025 at 03:10):

This is a pretty common pattern I write in imperative code, where I'll check a bunch of conditions and return early with errors

T : {field1, field2}
my_func = |a, b|
    if a.field1 > b.field1 then
        return Err(Error1)

    if a.field2 == 0 then
        return Err(Error2)

    if a.field1 * b.field2 > 100 then
        return Err(Error3)

    # preconditions passed, do logic with a and b
    # ....
    # return result of that calculation
    Ok({})

view this post on Zulip Richard Feldman (Feb 03 2025 at 03:12):

yeah I'd like to support this!

view this post on Zulip Ben (Feb 03 2025 at 03:16):

I guess it's a bit of an edge case for the language because if is supposed to be an expression and always have a matching else block? I think this could also extend to the crash and dbg keywords, where dbg has an effect for the user, and if you crash then there's no point of an else

view this post on Zulip Ben (Feb 03 2025 at 03:17):

e.g. I feel like it should be valid to replace the three returns above with crash or dbg and still have it compile

view this post on Zulip Ben (Feb 03 2025 at 03:17):

However I suppose it can remove some of the sense of purity / orthoganal-ness / consistency etc.?

view this post on Zulip Brendan Hansknecht (Feb 03 2025 at 03:30):

Yeah, now that we have return, we should be able to just make this work.

view this post on Zulip Brendan Hansknecht (Feb 03 2025 at 03:31):

Should also work with crash.

view this post on Zulip Brendan Hansknecht (Feb 03 2025 at 03:31):

Not sure about debug. Cause debug returns the passed in value after printing it

view this post on Zulip Oskar Hahn (Feb 03 2025 at 07:12):

Brendan Hansknecht said:

Not sure about debug. Cause debug returns the passed in value after printing it

Here is sounded, as if it could be possible: #ideas > conditional dbg @ 💬


Last updated: Jul 06 2025 at 12:14 UTC