diff options
| author | gingerBill <bill@gingerbill.org> | 2021-08-15 18:29:49 +0100 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2021-08-15 18:29:49 +0100 |
| commit | ac08d37ca0b2f8232669e8b2459905a6507fe9c2 (patch) | |
| tree | 68da71399461d964498ef8f95d6ed5d091595b65 /examples | |
| parent | 4035fec784fc7e0109d2f8a3d3bbfb5696512de1 (diff) | |
Add `or_return_operator` to examples/demo
Diffstat (limited to 'examples')
| -rw-r--r-- | examples/demo/demo.odin | 104 |
1 files changed, 100 insertions, 4 deletions
diff --git a/examples/demo/demo.odin b/examples/demo/demo.odin index eed633cd6..81bed8ce5 100644 --- a/examples/demo/demo.odin +++ b/examples/demo/demo.odin @@ -1998,9 +1998,9 @@ relative_data_types :: proc() { fmt.println(rel_slice[1]); } -or_else_procedure :: proc() { +or_else_operator :: proc() { fmt.println("\n#'or_else'"); - // IMPORTANT NOTE: 'or_else' is experimental features and subject to change/removal + // IMPORTANT NOTE: 'or_else' is an experimental feature and subject to change/removal { m: map[string]int; i: int; @@ -2029,6 +2029,102 @@ or_else_procedure :: proc() { } } +or_return_operator :: proc() { + fmt.println("\n#'or_return'"); + // IMPORTANT NOTE: 'or_return' is an experimental feature and subject to change/removal + // + // The concept of 'or_return' will work by popping off the end value in a multiple + // valued expression and checking whether it was not 'nil' or 'false', and if so, + // set the end return value to value if possible. If the procedure only has one + // return value, it will do a simple return. If the procedure had multiple return + // values, 'or_return' will require that all parameters be named so that the end + // value could be assigned to by name and then an empty return could be called. + + Error :: enum { + None, + Something_Bad, + Something_Worse, + The_Worst, + Your_Mum, + }; + + caller_1 :: proc() -> Error { + return .None; + } + + caller_2 :: proc() -> (int, Error) { + return 123, .None; + } + + foo_1 :: proc() -> Error { + // This can be a common idiom in many code bases + n0, err := caller_2(); + if err != nil { + return err; + } + + // The above idiom can be transformed into the follow + n1 := caller_2() or_return; + + + // And if the expression has no other, it can be used like this + caller_1() or_return; + // which is functionally equivalen to + if err1 := caller_1(); err1 != nil { + return err1; + } + + _, _ = n0, n1; + return .None; + } + foo_2 :: proc() -> (n: int, err: Error) { + // It is more common that your procedure turns multiple values + // If 'or_return' is used within a procedure multiple parameters (2+), + // then all the parameters must be named so that the remaining parameters + // so that a bare 'return' statement can be used + + // This can be a common idiom in many code bases + x: int; + x, err = caller_2(); + if err != nil { + return; + } + + // The above idiom can be transformed + y := caller_2() or_return; + + // And if the expression has no other, it can be used like this + caller_1() or_return; + + // which is functionally equivalen to + if err1 := caller_1(); err1 != nil { + err = err1; + return; + } + + // If a the other values need to be set depending on what the end value is, + // the 'defer if' is can be used + defer if err != nil { + n = -1; + } + + // If a non-bare return is required, then a normal if is a lot clearer + // and gets around the short circuiting + if z, zerr := caller_2(); zerr != nil { + n = -z; + err = zerr; + return; + } + + n = 123; + return; + } + + foo_1(); + foo_2(); +} + + main :: proc() { when true { the_basics(); @@ -2061,7 +2157,7 @@ main :: proc() { union_maybe(); explicit_context_definition(); relative_data_types(); - or_else_procedure(); + or_else_operator(); + or_return_operator(); } } -//
\ No newline at end of file |