From 50fbeeb0104d639dbf5d137f76516f7af74b9624 Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Sun, 23 Apr 2023 20:43:48 -0500 Subject: [PATCH] added: `Optional.try` --- core/container/optional.onyx | 52 ++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/core/container/optional.onyx b/core/container/optional.onyx index 6da427af..0afa32ff 100644 --- a/core/container/optional.onyx +++ b/core/container/optional.onyx @@ -106,6 +106,58 @@ package core #unquote body; } + #doc """ + Creates a scope that the `?` operator on an Optional type can + return to, instead of returning from the enclosing function. + + Useful when chaining a bunch of operations that *could* fail, + while having a clean and easy escape hatch. + + Optional.try() { + x := operation_1()?; + y := operation_2(x)?; + z := operation_3(x, y)?; + opreation_4(z); + } + println("Done"); + + In this example, if any of the operations fail, the execution + will cleanly go to `println` statement. + + To know when something returned `None`, you can either use the second + parameter called `catch`, which is simply a block of code to be run. + Or you can use the return result from the function as so: + + // Sadly, cannot use the nicer syntax, `try() { ... }` + completed := Optional.try(#quote { + // ... + }); + """ + try :: macro (body: Code, catch: Code = #quote {}) -> bool { + // + // Using a 'do'-expression block to introduce a new + // 'return' location. This way, when the code in the `body` + // does a `return return`, it will target this do-block. + _ := do -> u32 { + // + // Insert the body of interest. + #unquote body; + + // + // If execution makes it here, everything was successfuly + // and no `return return`s were encountered. Return true. + return return true; + }; + + #unquote catch; + + // + // If execution makes it here, there was an unexpected early + // return. Return false to signal the caller of this. + return false; + } + + hash :: (o: ?$T/core.hash.Hashable) -> u32 { if !o.has_value do return 0; return core.hash.hash(o.value); -- 2.25.1