If you want to play with "structurally typed condition handling", then the Koka language has "row-typed algebraic effect handlers" that compile to C: <http://koka-lang.org>
It's the name given to a specific idea being (re)explored in programming languages. Basically it's a try-catch except when you catch the error, you can do something, then return to where the exception was thrown and continue from there.
The second half of the article is similar to the idea of Algebraic Effects.
Here's another article explaining Algebraic Effects: https://overreacted.io/algebraic-effects-for-the-rest-of-us/
In high-school algebra, the variables 'x', 'y', etc. are mostly assumed to stand for numbers; but we still solve problems by chaining-together some basic 'things we can do'. For example, if we're given 'a + b = 2 × b' and we want to find an expression for 'a', we can do the following:
a + b = 2 × b (given)
(a + b) - b = (2 × b) - b (subtracting from both sides preserves equality)
a + (b - b) = (2 × b) - b (re-group + and -)
a + 0 = (2 × b) - b (replace 'x - x' with '0')
a = (2 × b) - b (replace 'x + 0' with 'x')
a = (b + b) - b ('2 × x' with 'x + x')
a = b + (b - b) (regroup again)
a = b + 0 (another 'x - x')
a = b (another 'x + 0')
Note that the above doesn't actually rely on 'a' and 'b' being numbers, or +/-/× being numeric addition/subtraction/multiplication; they can be anything, as long as they satisfy 'x - x = 0', 'x + 0 = x', etc."Interfaces", as found in Java, PHP, StandardML, etc. are algebras: as long as our value implements some interface Foo, we don't care what the implementation actually is. In fact, OOP was originally described in terms of "mini algebras" (what we would now call a "public interface", or "API").
The idea behind Algebraic Effects is that side-effects, like printing out strings, or sending network requests, can be treated in terms of 'what they do' (like an interface), rather than having to care about the implementation. A good example is code which has an input-reading effect: to run it, we must provide some implementation of 'input reading'; but the code will work the same regardless of whether we implement that effect by e.g. reading from the process's stdin handle, or from a GUI text box, or from a hard-coded string, or whatever.
So to evaluate a expression print("a") we pause evaluation, do the printing, and then resume it by returning () (or whatever value that print returns). So a language that has algebraic effects (or, equivalently, Common Lisp condition system) will be able to implement expressions that print to the terminal.