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