Add or_return_operator to examples/demo

This commit is contained in:
gingerBill
2021-08-15 18:29:49 +01:00
parent 4035fec784
commit ac08d37ca0

View File

@@ -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();
}
}
//