
What's a condition system and why do you want one? - fogus
http://axisofeval.blogspot.com/2011/04/whats-condition-system-and-why-do-you.html
======
danssig
Conditions are brilliant. This is something I wish more languages would copy
from CL. Having said that, this [1] is a better treatment of conditions, what
they can do and why you'd want them.

@Total_Meltdown Conditions are just that: _conditions_. Not necessarily errors
or exceptions. Exceptions are a subset of conditions ("exceptional" is a
condition). So if X is an error for your application you can unwind the stack
if you want to. Or you can try to fix the error in-place without trashing the
rest of whatever the program was doing. And yes, conditions allow one to
establish protocols between lower and higher levels of code.

The insight of conditions is that the code that detects the error may know
_ways_ of dealing with it but only higher level code can know what should
actually be done. There are other ways of dealing with this (e.g. passing
delegates) but all of them are much more clumsy than this system [2].

[1] [http://www.gigamonkeys.com/book/beyond-exception-handling-
co...](http://www.gigamonkeys.com/book/beyond-exception-handling-conditions-
and-restarts.html)

[2] Passing delegates was mentioned as a means of passing the condition
handling code, but the issue is that the code may be 20 layers down the stack.
Is every called method going to pass this delegate? Wont they have some
failure conditions themselves?

------
Total_Meltdown
This seems like a solution looking for a problem. There is a whole class of
code smell around using exceptions to direct logic flow. The only thing this
does that can't be done with if statements and delegates is lower the
importance of exceptions from "definitely an error" to "maybe an error, maybe
normal behavior". Maybe there are less contrived examples that better show off
what this feature could do, but it still smells fishy to me.

Edit: I realize that Java doesn't have delegates, but I would say that's a
point against Java, not a point in favor of this method.

~~~
arebop
Maybe you think Null Object Pattern or Maybe Monad are better ways to deal
with the article's motivating example problem. What about dealing with network
errors by exponential backoff and retry? What about the ask-the-user-what-to-
do policy the author mentions?

I'm not sure what you mean by delegates, but it sounds like you're saying that
you don't need special syntax for conditions when you have first-class
functions and simpler control-flow primitives. True, but sugar is nice
sometimes; I'd often rather have a list comprehension than a pile of gotos and
assignments.

~~~
Total_Meltdown
Yes, first-class functions are what I mean. (I come from a lot of C#
development, where functions-as-variables are called delegates.)

As for sugar, I agree that it's nice sometimes, but I disagree with extending
exception handling specifically. Exceptions are for errors, such as sending
data over a closed stream, or indexing an array out of bounds. This "condition
system" pattern encourages using exceptions for logic flow. Because why pass a
function all the way down the call stack when you can just throw an exception
to request that data from higher in the call stack, right?

Exceptions are errors, and they should be treated as such in all cases.

~~~
true_religion
>Exceptions are errors, and they should be treated as such in all cases.

This sounds an awful lot like a semantic argument.

If you have resumable exceptions, and can raise an exception deep in the stack
to ask higher-stack callers for more information then that's an _query_.

If you raise an exception in non-exceptional circumstances then that's a
scoped _announcement_.

The mere fact that in some languages they use the same run-time hooks as
exceptions is irrelevant.

Exceptions, where I first learned of them in Smalltalk derive from a prototype
class that isn't named Exception, and I've seen all manner of uses of the same
machinery in stack-twisting.

After all once you have full closures, and full control over your stack and
context why _shouldn't_ you use it for higher order abstractions involving the
stack-context?

------
mjw
Unless I'm getting the wrong end of the stick, this appears to use dynamic,
rather than lexical scope for the special non-stack-unwinding exception
handler blocks.

To me non-lexical scope is quite confusing, especially if you're proposing
adding it to a language (eg Java) which is otherwise lexically scoped.

IIRC lexical scope is generally preferred these days by language designers,
and Common Lisp is one of the few languages which supports dynamic scope
alongside lexical.

~~~
tomp
Yes, it isn't lexical scoping, it's dynamic, but that is the same way as
exception handlers are scoped currently.

~~~
mjw
Are they though? in which language?

I was under the impression that the traditional 'catch' block has the stack
unwound for it back to a frame with the same lexical scope as the associated
'try'...

~~~
tomp
Dynamic bindings are characterized by being bound not by the nearest preceding
code at compile-time, but by the nearest preceding code at run-time.

Therefore, the way I understand it, the important bit is not the relationship
between a _try_ and a _catch_ , but between the _throw_ and the _catch_. You
could imagine _throw_ as a call of the function _last_catch(Exception e)_ ,
which is dynamically bound by one of the "parent" functions (functions below
on the stack).

------
qntm
I'm still not 100% sure what the answer to the second question is. I think a
more compelling example is needed.

~~~
wladimir
I agree his example is a bit convoluted. But I can see how it is useful, for
example if you want to be able to retry operations after an I/O failure.

