Stream: announcements

Topic: New `return` and `try` keywords


view this post on Zulip Sam Mohr (Nov 04 2024 at 01:05):

The return keyword (PR) is now available for early returns in Roc! You can use it in if or when, even nested ones.

onlyCalculateWhenPositive = \n ->
    firstVal =
        if n <= 0 then
            return NoResult
        else
            n + 5

    Found (firstVal * 2)

The try keyword (PR) has also been merged. It should be in nightlies by . You can use it in place of ?, which is still supported for now but may be deprecated soon.

contents = try File.read! "my-file.txt"

contents = "my-file.txt" |> try File.read!

contents = File.read! "my-file.txt" |> try

view this post on Zulip Richard Feldman (Nov 04 2024 at 02:38):

yooooo, awesome work @Sam Mohr!!! :heart_eyes:

view this post on Zulip Richard Feldman (Nov 04 2024 at 02:38):

this is going to make Purity Inference so ergonomic! :grinning_face_with_smiling_eyes:

view this post on Zulip Jamie Neubert Pedersen (Nov 04 2024 at 17:41):

Really liking this direction of not having too many symbols, but using verbs instead :clap:

view this post on Zulip Sam Mohr (Nov 04 2024 at 17:42):

Roc is becoming a Forth dialect

view this post on Zulip Kevin Gillette (Nov 08 2024 at 19:55):

Too many parens and too few periods to be a Forth dialect

view this post on Zulip Kevin Gillette (Nov 08 2024 at 19:58):

Wouldn't the example clean up to look like the following?

onlyCalculateWhenPositive = \n ->
    if n <= 0 then
        return NoResult
    firstVal = n + 5
    Found (firstVal * 2)

view this post on Zulip Kevin Gillette (Nov 08 2024 at 20:00):

(it seems strange to use return alongside else, and to have the return "dodge around" the assignment that it's contained within)

view this post on Zulip Sam Mohr (Nov 08 2024 at 20:32):

Kevin Gillette said:

Wouldn't the example clean up to look like the following?

onlyCalculateWhenPositive = \n ->
    if n <= 0 then
        return NoResult
    firstVal = n + 5
    Found (firstVal * 2)

This is a feature we want to support but haven't implemented yet: https://github.com/roc-lang/roc/issues/7105

view this post on Zulip Sam Mohr (Dec 05 2024 at 11:24):

Between PR 1 and PR 2, the try and ? operators are now no longer just desugaring to other code, but are using a proper type-checking syntax! You should get better compiler errors when you use try or ? in a weird way. For example:

invalidTry = \{} ->
    nonResult = "abc"
    x = nonResult?

    Ok (x * 2)

invalidTry {}

Gives this error:

── INVALID TRY TARGET in /code/proj/Main.roc ───────────────────────────────────

This expression cannot be tried with the `?` operator:

6│          x = nonResult?
                ^^^^^^^^^^

I expected a Result, but it actually has type:

    Str

Hint: Did you forget to wrap the value with an `Ok` or an `Err` tag?

view this post on Zulip Anthony Bullard (Dec 05 2024 at 11:26):

This is such a relief! Thanks @Sam Mohr!

view this post on Zulip Luke Boswell (Dec 05 2024 at 11:27):

should get better compiler errors when you use try or ? in a weird way

Challenge accepted :salute:

view this post on Zulip Sam Mohr (Dec 05 2024 at 11:28):

Anthony Bullard said:

This is such a relief! Thanks Sam Mohr!

Happy to help! Let me know if you run into any issues.

My next task is to improve handling of early returns/try/? in statements, that pairs with this change well

view this post on Zulip Oskar Hahn (Dec 05 2024 at 11:28):

Is there a preference to use try or ?? Will both stay in Roc or will one be deprecated in the future?

view this post on Zulip Anthony Bullard (Dec 05 2024 at 11:29):

I think try may go away if/when static dispatch(with parens-and-commas) lands

view this post on Zulip Anthony Bullard (Dec 05 2024 at 11:30):

But I dont think it has to. Zig has try before the expression

view this post on Zulip Sam Mohr (Dec 05 2024 at 11:31):

Either would work, but ? is syntactically much more compatible with static dispatch, so it's pretty likely we'll get rid of try to maintain the "one way to do things" goal

view this post on Zulip Anthony Bullard (Dec 05 2024 at 11:31):

I hope we keep both through the first few months of static dispatch and get feedback before committing to one

view this post on Zulip Sam Mohr (Dec 05 2024 at 11:31):

Okay, we can do that

view this post on Zulip Sam Mohr (Dec 05 2024 at 11:32):

It wouldn't be too much of a compiler complexity burden to do so

view this post on Zulip Anthony Bullard (Dec 05 2024 at 11:32):

Do we want to be more symbol-y or more keyword-y I think is the big design question

view this post on Zulip Anthony Bullard (Dec 05 2024 at 11:32):

I tried to create a language in the same design space that had NO keywords and had commas and parens

view this post on Zulip Anthony Bullard (Dec 05 2024 at 11:32):

But it had almost zero sugar

view this post on Zulip Anthony Bullard (Dec 05 2024 at 11:33):

And no prefix, postfix, or binary operators :rofl:

view this post on Zulip Anthony Bullard (Dec 05 2024 at 11:34):

Jamie Neubert Pedersen said:

Really liking this direction of not having too many symbols, but using verbs instead :clap:

But I think this sentiment is common, especially for people coming from C/ALGOL descendants

view this post on Zulip Sam Mohr (Dec 05 2024 at 11:35):

A lot of work has been moving towards symbols where possible, but there are some places where operators are just better, since they're great at visually breaking up things

view this post on Zulip Sam Mohr (Dec 05 2024 at 11:37):

The main example is when arrows. We discussed maybe doing when and then:

when result is
    Ok val then abc
    Err err then def

The branch patterns and bodies are harder to distinguish than with arrows

when result is
    Ok val -> abc
    Err err -> def

view this post on Zulip Sam Mohr (Dec 05 2024 at 11:39):

Syntax highlighting helps, but it's still worse IMO

view this post on Zulip Oskar Hahn (Dec 05 2024 at 11:43):

Maybe it is a good thing to have ? and try for the moment. I don't have any preference. I realise, that I am using both without a system. Sometimes ? and sometimes try. Maybe this is a good experiment, if a symbol or a keyword is better. But I hope that in a 1.0, where will be a clear system and only one way to do it.

view this post on Zulip Sam Mohr (Dec 05 2024 at 11:44):

I agree with you on everything there

view this post on Zulip jan kili (Dec 05 2024 at 16:33):

Ooh ?! is back on the table, then :smiley:

view this post on Zulip jan kili (Dec 05 2024 at 16:34):

Oops I mean !?

view this post on Zulip jan kili (Dec 05 2024 at 16:36):

And now !?. between names

view this post on Zulip Richard Feldman (Dec 05 2024 at 16:50):

well with parens and commas it would always be foo!()?

view this post on Zulip Richard Feldman (Dec 05 2024 at 16:52):

foo!? would be a type mismatch because the ! suffix naming convention would only be for functions, and functions aren't Results, so using ? on one directly would always be a type mismatch :big_smile:

view this post on Zulip Dan G Knutson (Dec 05 2024 at 16:53):

But Task is gone, so I can no longer alias Task.fromResult to really

view this post on Zulip jan kili (Dec 05 2024 at 17:00):

Ohhh gotcha, I didn't realize empty () would be required. (Makes sense.)

view this post on Zulip jan kili (Dec 05 2024 at 17:08):

So then
the |> old |> try idiomatic! |> roc! style
the.new().idiomatic!()?.roc!(style)

view this post on Zulip Nicola Peduzzi (Dec 05 2024 at 18:24):

so if I get this right try ( anythingThatIsAResult ) is equivalent to ( anythingThatIsAResult )? correct?

and where is this new aTask!()? style coming from?

view this post on Zulip Sam Mohr (Dec 05 2024 at 18:25):

Yes, those are equivalent

view this post on Zulip Sam Mohr (Dec 05 2024 at 18:27):

The new style is from the pretty much accepted static dispatch proposal:

https://docs.google.com/document/d/1OUd0f4PQjH8jb6i1vEJ5DOnfpVBJbGTjnCakpXAYeT8/edit

view this post on Zulip Sam Mohr (Dec 05 2024 at 18:28):

https://roc.zulipchat.com/#narrow/stream/304641-ideas/topic/static.20dispatch.20-.20proposal/near/481417068

view this post on Zulip jan kili (Dec 05 2024 at 18:31):

Do they both interrupt the function and early return on Err? Visually (or thinking of other languages), when used in a .chain the ? looks to me like it would just interrupt the chain.

view this post on Zulip Sam Mohr (Dec 05 2024 at 18:33):

They literally use the same code, so yes

view this post on Zulip Anthony Bullard (Dec 05 2024 at 19:12):

Sam Mohr said:

The new style is from the pretty much accepted static dispatch proposal:

https://docs.google.com/document/d/1OUd0f4PQjH8jb6i1vEJ5DOnfpVBJbGTjnCakpXAYeT8/edit

How do proposals become "accepted"? Is that process documented somewhere?

view this post on Zulip Sam Mohr (Dec 05 2024 at 19:13):

Lmao nope

view this post on Zulip Anthony Bullard (Dec 05 2024 at 19:13):

I had kinda thought Richard just did the BDFL thing

view this post on Zulip Sam Mohr (Dec 05 2024 at 19:14):

That's true, but it's more that Rich is just the one who made the proposal this time

view this post on Zulip Sam Mohr (Dec 05 2024 at 19:16):

In general:

view this post on Zulip Sam Mohr (Dec 05 2024 at 19:16):

Nothing formal

view this post on Zulip Sam Mohr (Dec 05 2024 at 19:17):

We do have an RFC repo, but it's not really used

view this post on Zulip Anthony Bullard (Dec 05 2024 at 19:17):

Cool, so no 5 Stage process, quarterly plenaries, and consensus gathering amongst 100s of stakeholders?

view this post on Zulip Anthony Bullard (Dec 05 2024 at 19:17):

:rofl:

view this post on Zulip Sam Mohr (Dec 05 2024 at 19:17):

This is vibes-based proposals

view this post on Zulip Anthony Bullard (Dec 05 2024 at 19:17):

(This was a TC-39 subtweet)

view this post on Zulip Anthony Bullard (Dec 05 2024 at 19:18):

Both processes make sense for where the respective languages are, and their environment

view this post on Zulip Luke Boswell (Dec 05 2024 at 19:32):

We have this https://www.roc-lang.org/community#ideas


Last updated: Jul 26 2025 at 12:14 UTC