August 24, 2022

On 8/24/22 4:07 PM, user1234 wrote:

>

On Wednesday, 24 August 2022 at 18:15:53 UTC, ryuukk_ wrote:

>

I want to point out that, just like with the GC, it is not the panacea, if you have a NaN in your result, good luck finding what is the root of the issue/bug in your program, or library.. it is during moments like that that i still prefer it being 0 by default, so everyone is on the same page

In gdb you can use select-frame and inspect the value of locals of the whole call stack. Also just bt can help as that shows the call args values.

The source may not be in the call stack.

-Steve

August 24, 2022
On 8/24/2022 11:11 AM, ryuukk_ wrote:
> That's the best answer possible, i used to be annoyed by float not being 0 by default, but as i learn more and read different takes on it, it makes sense, and i don't mind anymore
> 
> The main issue is to get used to it, it takes time if you use other languages that defaults to 0

It's one reason why D is simply better than those other languages.

(Not many language designers have experience doing commercial floating point work, and it shows. I was an early member of NCEG (Numerical C Extensions Group) which worked hard to add proper floating point support to the C Standard, including exacting support for NaN. I implemented it in Zortech C/C++ years before anyone else did.)
August 24, 2022
On 8/24/2022 11:15 AM, ryuukk_ wrote:
> I want to point out that, just like with the GC, it is not the panacea, if you have a NaN in your result, good luck finding what is the root of the issue/bug in your program, or library.. it is during moments like that that i still prefer it being 0 by default, so everyone is on the same page

I can't think of a case where a 0 is easier to track back to its origin.
August 24, 2022
On 8/24/2022 7:03 AM, Steven Schveighoffer wrote:
> I actually proved this too with a test, so that's good news! Maybe I just need to define all my structs using C :P

You could, but NaN default initialization is better.

I inferred that you relied on detecting a wrong 0 initialization by looking for unexpected behavior. This is less reliable than looking for a NaN in the output. When the behavior of a mistake being most of the time it will work out ok, is not acceptable because there's that case where it won't be ok and could be very costly.

It should not be "the output looks sort of right, so assume it is right." It should *be* right, or be *obviously* wrong.

People should have to explicitly work at getting it wrong.

These are more of those lessons I picked up from working on flight controls at Boeing.

For example, hydraulic actuators (rams) drive the flight control surfaces back and forth. The actuators have a hydraulic fluid input port, and an output port. If the hydraulic lines are hooked to the wrong ports, the airplane will be uncontrollable and will crash. This has happened many times in the past. Boeing's solution is to:

1. the ports are different sizes
2. one is a left-hand thread, the other is a right-hand thread
3. the lines and ports are color-coded
4. the lines are laid out so the hydraulic lines are not long enough to connect to the wrong port
5. inspectors have to sign off on it
6. the flight controls are tested for correct operation as part of the pre-flight checklist

This has stopped the problem. Note how hard a mechanic would have to work to get it wrong, and if he succeeded it would be *obviously* wrong to the inspector.

I try to infuse this philosophy into D's design where ever it fits.
August 25, 2022
On Thursday, 25 August 2022 at 01:19:55 UTC, Walter Bright wrote:
> If the hydraulic lines are hooked to the wrong ports, the airplane will be uncontrollable and will crash.

oh ye of little faith!

I read about a story where this happened. The pilots quickly found the plane uncontrollable to the point where they asked for vectors to ditch into the ocean so the crash wouldn't hurt anybody on the ground at least... but they couldn't even control it well enough to successfully navigate out there. They kept flying in random directions and ended up over ground again, but had enough altitude to keep trying again.

After quite some time though, they actually recognized the "random, uncontrollable" aircraft actually was responding to their inputs in a predictable pattern, it was just all messed up. As they figured it out and learned how to fly with these bizarro controls, their initial panic subsided and they were able to successfully return to the airport for a safe landing!

(of course there are other similar stories without the happy ending so your point is good, but i like this story)
August 25, 2022

On Thursday, 25 August 2022 at 01:19:55 UTC, Walter Bright wrote:

>

Boeing.

Now Boeing is a fighter among missiles.

August 24, 2022

On 8/24/22 9:19 PM, Walter Bright wrote:

>

On 8/24/2022 7:03 AM, Steven Schveighoffer wrote:

>

I actually proved this too with a test, so that's good news! Maybe I just need to define all my structs using C :P

You could, but NaN default initialization is better.

I inferred that you relied on detecting a wrong 0 initialization by looking for unexpected behavior. This is less reliable than looking for a NaN in the output. When the behavior of a mistake being most of the time it will work out ok, is not acceptable because there's that case where it won't be ok and could be very costly.

No, you are completely misunderstanding what I'm saying.

What I was saying is that NaN is not that much different from 0 when the outputs you have aren't "val = NaN". I.e. most of the time.

Once you have determined there is a problem, I don't really think NaN helps much finding the source -- the source can be long gone by the time you attach a debugger. The correct mechanism is to look at what possible places the value could be written, and trace it back to the incorrect value.

But what I am saying is that I frequently omit initialization of numbers I expect to start at 0. I forget that double is NaN by default, and then I have to find and fix that. The only thing NaN has ever done for me is found places where I forgot to initialize to 0.

>

It should not be "the output looks sort of right, so assume it is right." It should be right, or be obviously wrong.

People should have to explicitly work at getting it wrong.

These are more of those lessons I picked up from working on flight controls at Boeing.

NaN fails at that. It's silently swallowed by just about everything. Only when a human looks at some printout does it become obvious.

A better option would be to throw an exception if NaN is used in an operation.

>

For example, hydraulic actuators (rams) drive the flight control surfaces back and forth. The actuators have a hydraulic fluid input port, and an output port. If the hydraulic lines are hooked to the wrong ports, the airplane will be uncontrollable and will crash. This has happened many times in the past. Boeing's solution is to:

  1. the ports are different sizes
  2. one is a left-hand thread, the other is a right-hand thread
  3. the lines and ports are color-coded
  4. the lines are laid out so the hydraulic lines are not long enough to connect to the wrong port
  5. inspectors have to sign off on it
  6. the flight controls are tested for correct operation as part of the pre-flight checklist

This has stopped the problem. Note how hard a mechanic would have to work to get it wrong, and if he succeeded it would be obviously wrong to the inspector.

I try to infuse this philosophy into D's design where ever it fits.

I understand, but NaN is woefully inadequate for the task.

NaN is more like if you hooked up the ports wrong, a dye is added to the fluid, which isn't visible through the tubes. You have to extract and examine the fluid to realize something is wrong. Then you have to find the source of the dye (and it could come from anywhere in the system).

-Steve

August 25, 2022

On Thursday, 25 August 2022 at 03:08:54 UTC, Steven Schveighoffer wrote:

>

A better option would be to throw an exception if NaN is used in an operation.

-Steve

IMHO this is the better solution and not even an exception, but Error.

As soon as you have any NaN values that are being used your program is effectively useless and broken.

I think as soon as any variable becomes NaN it should throw, not just when an operation happens.

Basically I think it should throw when either of these conditions holds true:

  • A value was initialized as NaN and used in an operation
  • A value was set to NaN outside of initialization
  • NaN is returned from a function (Even if not set to a variable or anything.)

This will solve all problems because:

  • You will never have a NaN value propagate throughout your program, making it much easier to track it back to its roots.
  • NaN strictly tells you that some value is wrong before it's even being used
  • There's no way to workaround it effectively, meaning you must actually fix any places where NaN is possible.
August 25, 2022

On Thursday, 25 August 2022 at 03:08:54 UTC, Steven Schveighoffer wrote:

>

by default, and then I have to find and fix that. The only thing NaN has ever done for me is found places where I forgot to initialize to 0.

One big advantage of having everything default to 0 would be if the compiler was clever and used pre-cleared memory for arrays. That way you don't have to do any constructor work.

August 25, 2022

On Thursday, 25 August 2022 at 07:15:58 UTC, bauss wrote:

>

On Thursday, 25 August 2022 at 03:08:54 UTC, Steven Schveighoffer wrote:

>

A better option would be to throw an exception if NaN is used in an operation.

-Steve

IMHO this is the better solution and not even an exception, but Error.

As soon as you have any NaN values that are being used your program is effectively useless and broken.

I think as soon as any variable becomes NaN it should throw, not just when an operation happens.

Basically I think it should throw when either of these conditions holds true:

  • A value was initialized as NaN and used in an operation
  • A value was set to NaN outside of initialization
  • NaN is returned from a function (Even if not set to a variable or anything.)

I'm shocked by this idea. What if I want high performance nothrow FP code ?