|No such thing as a small change|
You're really gonna hate any() values (and traits) when Perl6 comes around. ;-)
If you want more information about what went wrong, put more values into the return set. You know.. like NaN, positive and negative infinity, "Number outside representation range" and that sort of thing. You could also add utility values like positive and negative zero, or 'Infinitesimal' which make certain calculations easier.
If you want even more information, you can choose which of:
fits your purposes best.
You're also missing the point that value should always contain something consumable by the main-line client code. The goal is "usable but identifiably bogus" rather than "broken but correct."
If I were writing a division operator, for instance, I'd probably have division by zero return:
The one in value is consumable by any other mathematical operation, even though it's totally bogus as an accurate result of the calculation. The boolean in is-valid tells you it's bogus, and the detail code in error tells you why. (Yeah, error is new. I added more information. We can do that)
If I really wanted to get spiffy, I'd add still more information:
then write all my operators so they return progressively more complicated trace strings whenever they get invalid arguments. That way, I could see at a glance where the error occured, rather than having to fire up a debugger and step through the code until it bombs out again.
IMO, the presence of exceptions is a code smell. It says that you'd rather use the quantum superposition of two (or more) possible code sequences in a "try it, then backtrack and see what went wrong" fashion rather than figuring out how to make the code work in the first place. And it's almost always a sign that the programmer is trying to use a data representation that's too primitive to handle all the results that are actually possible.
So.. you can write Schrodinger-code to compensate for the bad decisions you made about data representation, or you can choose a data representation that actually does what it's supposed to, and handle the job correctly.