Is it just me, or do restarts sound a bit like coroutines combined with ADTs? In Python or JavaScript, you can use the yield keyword to “yield” control to the calling code along with a current result. If the yield type was an enum/variant (for example, a result), then it would be similar to the concept of a restart.
Another issue is just in performance. In an error or try/catch system you unwind the stack along the way. In a condition system, you don't. If you insisted on manually passing them up until you find a handler (or not, in which case it may become an effective noop), you have to touch all of that "is it a condition or result" logic all the way up, and then resume all the way back down, and then return to the top of a loop because you could get another condition. So you'd end up writing something more like this:
do {
result = call(...);
if is_condition(result) {
// possibly handle it or re-yield
switch(result) {
log: ...
other_condition: ...
default: yield result;
}
}
} while(is_condition(result));
It should work, but it seems like it would be unpleasant to work with. With a condition system, you may implement it in a way that forces this kind of costly search through the call stack, or you could register the handlers and avoid this costly backtrack and resume operation.