aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2021-08-15 18:29:49 +0100
committergingerBill <bill@gingerbill.org>2021-08-15 18:29:49 +0100
commitac08d37ca0b2f8232669e8b2459905a6507fe9c2 (patch)
tree68da71399461d964498ef8f95d6ed5d091595b65 /examples
parent4035fec784fc7e0109d2f8a3d3bbfb5696512de1 (diff)
Add `or_return_operator` to examples/demo
Diffstat (limited to 'examples')
-rw-r--r--examples/demo/demo.odin104
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