Yep…I’ve started to use some of those in certain situations and they are great help. The Option.get is frustrating because if you any kind of complex type you have to create a “default” for it. Not a big deal, but if the type is complex things like equivalence become difficult.
I would love something like Option.get(x, return #error(“some error”), but you can’t do that because the second parameter is executed before being passed to the function.
Using @paulyoung 's I could do
let x = if(Foo.nat(y) != null){return Foo.nat(y);}ele {return #error("some error"};
but that is almost as hard as having to read as scrolling up to figure out what .nat does. I’m interested in trying to increase the amount of information conveyed to the reader with the fewest bits possible and about 80% of the solution is boilerplate.
If I’ve tested if something is null and reacted to it I probably want to use the unwrapped version elsewhere in my code. So I end up with this pattern everywhere:
let x :Nat = switch(x){
case(null){ return #error("x was null, try again")};
case(?x){x};
}
I’ve highlighted the cruft that conveys no information:
Something like the following would make the language much more elegant
//unwrap the variable unless it nulls out; if it nulls out then execute the block
let x : Text = take(x!){return #error("x was null, try again)};
and
//match the var to the pattern and execute the block; else return null
let x : ?Text = match(x,#variant(val)){val;}
together
let x : Text = take(match(x, #variant(val){val}){ return #error("x was null, try again)};