I'm experimenting with a solution in C3 that has this behaviour. I don't have a sum type as such, but the binding acts as one. I call the binding a "failable".
int! a = getMayError();
// a is now either an int, or contains an error value.
// foo(a) is only conditionally invoked.
int! b = foo(a);
// The above works as if it was written:
// int! b = "if a has error" ? "the error of a" : foo("real value of a");
// A single if-catch with return will implicitly unwrap:
if (catch err = b) {
/* handle errors */
return;
}
/* b is unwrapped implicitly from here on and is treated as int */
if (try int x = a) {
/* conditionally execute if a isn't an error */
}
I think this is kind of formalizing the poison technique but external from the call (that is, "foo" does not need to know about "failables" or return one, the call is skipped on the caller side). Here are some more examples:
http://www.c3-lang.org/errorhandling/I'd be interested in hearing what you think about this (experimental) solution Walter.