From 9d927e281451ce44fc880033e3da92679caaf183 Mon Sep 17 00:00:00 2001 From: Norbert Hajagos Date: Fri, 27 Feb 2026 21:27:09 +0100 Subject: [PATCH 1/2] update TryOperatorDesugaring to new compiler --- ci_scripts/all_tests.sh | 1 + examples/TryOperatorDesugaring/README.md | 20 +++--- examples/TryOperatorDesugaring/main.roc | 79 ++++++++++++++++-------- 3 files changed, 67 insertions(+), 33 deletions(-) diff --git a/ci_scripts/all_tests.sh b/ci_scripts/all_tests.sh index f31cb310..79a948aa 100755 --- a/ci_scripts/all_tests.sh +++ b/ci_scripts/all_tests.sh @@ -17,6 +17,7 @@ fi # opt-in list of examples to test (add examples as they are updated for the new compiler) optin=( + "TryOperatorDesugaring" ) is_optin() { diff --git a/examples/TryOperatorDesugaring/README.md b/examples/TryOperatorDesugaring/README.md index f6e854dd..e56308bd 100644 --- a/examples/TryOperatorDesugaring/README.md +++ b/examples/TryOperatorDesugaring/README.md @@ -8,32 +8,39 @@ convenient way without adding new functionality to the language itself. -Desugaring converts syntax sugar (like `x + 1`) into more fundamental operations (like `Num.add(x, 1)`). +Desugaring converts syntax sugar (like `x + 1`) into more fundamental operations (like `x.plus(1)`). Let's see how `?` is desugared. In this example we will extract the name and birth year from a string like `"Alice was born in 1990"`. + ```roc file:main.roc:snippet:question ``` After desugaring, this becomes: + ```roc file:main.roc:snippet:desugared ``` -So `birth_year = Str.to_u16(birth_year_str)?` is converted to +So `birth_year = U16.from_str(birth_year_str)?` is converted to ```roc -when Str.to_u16(birth_year_str) is - Err(err2) -> return Err(err2) - Ok(birth_year) -> birth_year +birth_year = match U16.from_str(birth_year_str) { + Err(err) => { + return Err(err) + } + Ok(value) => value +} ``` + As you can see, the first version is a lot nicer! Thanks to `?`, you can write code in a familiar way and you get the benefits of Roc's error handling to drastically reduce the likelihood of crashes. ## Full Code + ```roc file:main.roc ``` @@ -44,6 +51,5 @@ Run this from the directory that has `main.roc` in it: ``` $ roc main.roc -Ok({birth_year: 1990, name: "Alice"}) -Ok({birth_year: 1990, name: "Alice"}) +Bob is older than Alice ``` diff --git a/examples/TryOperatorDesugaring/main.roc b/examples/TryOperatorDesugaring/main.roc index d703007c..a945f34f 100644 --- a/examples/TryOperatorDesugaring/main.roc +++ b/examples/TryOperatorDesugaring/main.roc @@ -1,36 +1,63 @@ -app [main!] { cli: platform "https://github.com/roc-lang/basic-cli/releases/download/0.20.0/X73hGh05nNTkDHU06FHC0YfFaQB1pimX7gncRcao5mU.tar.br" } +main! : List(Str) => Try({}, _) +main! = |_args| { + person1 = parse_name_and_year("Alice was born in 1990")? + person2 = parse_name_and_year_try("Bob was born in 1985")? -import cli.Stdout -import cli.Arg exposing [Arg] + msg = if person1.birth_year < person2.birth_year { + "${person1.name} is older than ${person2.name}" + } else { + "${person2.name} is older than ${person1.name}" + } + echo!(msg) + Ok({}) +} -main! : List Arg => Result {} _ -main! = |_args| - Stdout.line!(Inspect.to_str(parse_name_and_year("Alice was born in 1990")))? - Stdout.line!(Inspect.to_str(parse_name_and_year_try("Alice was born in 1990")))? +### start snippet question +parse_name_and_year : Str -> Try({ name : Str, birth_year : U16 }, _) +parse_name_and_year = |str| { + words = str.split_on(" ") - Ok({}) + name = words.first()? -### start snippet question -parse_name_and_year : Str -> Result { name : Str, birth_year : U16 } _ -parse_name_and_year = |str| - { before: name, after: birth_year_str } = Str.split_first(str, " was born in ")? - birth_year = Str.to_u16(birth_year_str)? - Ok({ name, birth_year }) + birth_year_str = List.last(words)? + # TODO: commented out line causes this panic: + # Interpreter error: error.InvalidMethodReceiver + # Execution error: error.InterpreterFailed + # birth_year_str = words.last()? + # + birth_year = U16.from_str(birth_year_str)? + + Ok({ name, birth_year }) +} ### end snippet question ### start snippet desugared -parse_name_and_year_try = |str| - when Str.split_first(str, " was born in ") is - Err(err1) -> - return Err(err1) - - Ok({ before: name, after: birth_year_str }) -> - when Str.to_u16(birth_year_str) is - Err(err2) -> - return Err(err2) - - Ok(birth_year) -> - Ok({ name, birth_year }) +parse_name_and_year_try = |str| { + words = str.split_on(" ") + name = match words.first() { + Err(err) => { + return Err(err) + } + Ok(value) => value + } + + # TODO: same as above + birth_year_str = match List.last(words) { + Err(err) => { + return Err(err) + } + Ok(value) => value + } + + birth_year = match U16.from_str(birth_year_str) { + Err(err) => { + return Err(err) + } + Ok(value) => value + } + + Ok({ name, birth_year }) +} ### end snippet desugared expect parse_name_and_year("Alice was born in 1990") == Ok({ name: "Alice", birth_year: 1990 }) From 6ce6325f53d76dead53230a63ccd0158e059a71b Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Sat, 28 Feb 2026 16:57:13 +0100 Subject: [PATCH 2/2] misc additions and improvements --- ci_scripts/all_tests.sh | 1 - ci_scripts/check_format.sh | 1 + ci_scripts/expect_scripts/TryOperatorDesugaring.exp | 4 ++-- examples/TryOperatorDesugaring/main.roc | 2 ++ 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/ci_scripts/all_tests.sh b/ci_scripts/all_tests.sh index 79a948aa..8fb6d4a5 100755 --- a/ci_scripts/all_tests.sh +++ b/ci_scripts/all_tests.sh @@ -96,7 +96,6 @@ if is_optin "CommandLineArgsFile"; then fi if is_optin "TryOperatorDesugaring"; then - $ROC build ./examples/TryOperatorDesugaring/main.roc $ROC test ./examples/TryOperatorDesugaring/main.roc expect ci_scripts/expect_scripts/TryOperatorDesugaring.exp fi diff --git a/ci_scripts/check_format.sh b/ci_scripts/check_format.sh index f51796c1..97ae72f5 100755 --- a/ci_scripts/check_format.sh +++ b/ci_scripts/check_format.sh @@ -18,6 +18,7 @@ fi # opt-in list of files to format check (add files as they are updated for the new compiler) optin=( + "examples/TryOperatorDesugaring/main.roc" ) for file in "${optin[@]}"; do diff --git a/ci_scripts/expect_scripts/TryOperatorDesugaring.exp b/ci_scripts/expect_scripts/TryOperatorDesugaring.exp index 8cb17f7e..9f14c192 100644 --- a/ci_scripts/expect_scripts/TryOperatorDesugaring.exp +++ b/ci_scripts/expect_scripts/TryOperatorDesugaring.exp @@ -7,9 +7,9 @@ set timeout 7 source ./ci_scripts/expect_scripts/shared-code.exp -spawn ./examples/TryOperatorDesugaring/main +spawn $env(ROC) ./examples/TryOperatorDesugaring/main.roc --no-cache -expect -exact "(Ok {birth_year: 1990, name: \"Alice\"})\r\n(Ok {birth_year: 1990, name: \"Alice\"})\r\n" { +expect -exact "Bob is older than Alice\r\n" { expect eof { check_exit_and_segfault } diff --git a/examples/TryOperatorDesugaring/main.roc b/examples/TryOperatorDesugaring/main.roc index a945f34f..ac31a3a1 100644 --- a/examples/TryOperatorDesugaring/main.roc +++ b/examples/TryOperatorDesugaring/main.roc @@ -8,7 +8,9 @@ main! = |_args| { } else { "${person2.name} is older than ${person1.name}" } + echo!(msg) + Ok({}) }