Motivation
With the try? operator, it’s easy to convert errors to optional values, which is useful for working with external code or when it’s unimportant what the error is. However, sometimes we want to handle some errors differently. To do this we need to use a do-catch statement. In the worst case, we need nested do statements.
Proposal
The syntax of optional-try expressions is extended to allow specifying a filter on the error. If the error matches the filter, it is suppressed and the expression evaluates to nil. But if the error doesn’t match, it is propagated. Therefore, such expressions can only occur inside do blocks or throwing functions.
Syntax possibilities
Here, some syntax allows filtering by type only, and some by pattern.
try? is Problem f()
Here,is Problemlooks like a pattern. But if we allow any pattern, the syntax is ambiguous.try? throws(Problem) f()
Here, instead ofProblem, we could allow patterns and writeis Probleminstead.(Problem) try? f()
dittotry? case Problem.specific f()
This could allow a shorthand if the pattern is justiswherecaseis elidedProblem.try? f()
Possibly this could allow patterns, but that might be confusing to read or ambiguoustry? guard Problem f()
Again, a pattern is possibletry? f() if is Problemortry? f() case Problem.specific
Most of these are probably ambiguous in some way and would require some careful precedence rules.
In many of these it could be a good idea to require braces, but in that case it becomes hardly shorter than a nested do statement, and it’d be unclear why the braces don’t contain statements, but expressions.