A Philosophy of Software Design
Walter Bright
newshound2 at digitalmars.com
Sun Jun 28 02:35:23 UTC 2026
On 6/27/2026 12:44 PM, H. S. Teoh wrote:
> OTOH, it merely shoves the problem elsewhere: now you cannot rely on your
> values being real values: NaN poisons all subsequent calculations and
> now downstream code has to worry about what to do if the input is NaN.
The choice is:
1. the answer is NaN, so you know there is a problem with the code
2. the answer is a number, so you don't know if there is a problem with the code
I choose (2) as the preferable option.
> E.g., sqrt() is involved in some calculation that eventually ends up as
> the dimensions of some on-screen object. Now your rendering code has to
> deal with the problem of how to draw an object with NaN dimensions.
> (Complexity added: an extra NaN check in render() to prevent it from
> going off the rails when it tries to loop from 0 to NaN. Or extra NaN
> checks somewhere in-between to prevent it from getting into the render
> queue and reaching the render function in the first place. Either way
> you haven't eliminated complexity, merely shoved it into a different
> form which has to be handled elsewhere.)
I prefer errors to be obvious rather than papered over.
> Sometimes throwing an exception *is* the least complex way to deal with
> the problem. In opening a file, for example, instead of throwing an
> exception, you *could* return a dummy object in place of a file if the
> file doesn't exist, or the filesystem is corrupt, or some other error
> occurs. Yes you got rid of a throw statement, but at what cost? Now
> downstream code has to deal with a dummy file object. Does it continue
> processing it as a normal file of 0 size? What if the program needs to
> differentiate between "file not found" vs. "filesystem is corrupt"?
> What if an empty file is valid input, and you need to differentiate that
> from an error condition? Somewhere down the line, *somebody* has to
> deal with the exceptional condition somehow. A single throw statement
> is less complexity than a bunch of special code to differentiate between
> an empty file and a dummy file representing an error state.
A reasonable question. Consider:
```d
err = fprintf(stdout,"hello ");
if (err)
handleIt();
err = fprintf(stdout,"betty\n");
if (err)
handleIt();
```
as opposed to:
```d
fprintf(stdout,"hello ");
fprintf(stdout,"betty\n");
if (stdout.isError)
handleIt();
```
Which would you prefer?
(The downstream code shouldn't have to deal with a dummy file object. It should
just deal with the file object as if it succeeded. The file object in an error
state would simply do nothing.)
I know I'm pushing upstream with this notion. I know it is not the conventional
wisdom. But it has a lot of potential to significantly simplify code and
eliminate a lot of untested error paths. It is worth looking into.
More information about the Digitalmars-d
mailing list