digitalmars.D.learn - Floating point types default to NaN?
- A Guy With a Question (3/3) Nov 24 2017 I would have expected 0 to be the default value. What's the logic
- Adam D. Ruppe (14/16) Nov 24 2017 It gives you a runtime error (sort of) if you use an
- A Guy With a Question (5/22) Nov 24 2017 If thats the case why not just throw a compiler error? D has a
- Jonathan M Davis (25/52) Nov 24 2017 That requires data flow analysis, which the compiler doesn't do a lot of...
- Dave Jones (9/20) Nov 25 2017 I think he means just spew an error if a float is declared but
- A Guy With a Question (7/27) Nov 25 2017 That is exactly what I meant. I think most languages just choose
- A Guy With a Question (2/2) Nov 25 2017 Nonetheless, my original question was answered. Thanks for the
- Adam D. Ruppe (19/22) Nov 25 2017 It technically did:
- A Guy With a Question (3/25) Nov 25 2017 Fair enough!
- Steven Schveighoffer (6/32) Nov 27 2017 I rely on the default value initialization all the time! I don't know
- Adam D. Ruppe (14/19) Nov 27 2017 Yes, indeed, me too. I like it now.
- Michael V. Franklin (8/20) Nov 27 2017 WOW!! I am shocked to learn this. All this time, I though it was
- Michael V. Franklin (5/8) Nov 28 2017 Well, I implemented it (https://github.com/dlang/dmd/pull/7375),
- A Guy With a Question (5/15) Nov 28 2017 To be honest, I didn't actually expect anyone to act on my
- Michael V. Franklin (5/6) Nov 28 2017 So am I. I'm trying to get to the heart of in the the PR
- A Guy With a Question (5/11) Nov 28 2017 That's a lot less code than I would have thought to implement
- Dukc (18/20) Nov 27 2017 Debatable in this case. Consider:
- Adam D. Ruppe (5/8) Nov 27 2017 Well, the compiler can see it is initialized before being read
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (9/14) Nov 25 2017 If dataflow is sufficient then it isn't all that complicated, you
- codephantom (3/6) Nov 29 2017 http://www.drdobbs.com/cpp/nans-just-dont-get-no-respect/240005723
I would have expected 0 to be the default value. What's the logic behind having them being NaN by default? https://dlang.org/spec/type.html
Nov 24 2017
On Friday, 24 November 2017 at 14:30:44 UTC, A Guy With a Question wrote:I would have expected 0 to be the default value. What's the logic behind having them being NaN by default?It gives you a runtime error (sort of) if you use an uninitialized variable. You ARE supposed to explicitly initialize variables to your own values in D. The automatic init is to make errors stand out more consistently if you don't do this as opposed to being random. So pointers are initialized to null - an invalid value that stands out if you try to use it. chars get \xFF - again, invalid that will throw if you try to utf decode it. Floats get NaN which is as close to invalid as they get. ints happen to get 0 not to be convenient, but because there is no clearly-invalid int value so something had to be chosen, and 0 was just easy to implement....
Nov 24 2017
On Friday, 24 November 2017 at 14:43:24 UTC, Adam D. Ruppe wrote:On Friday, 24 November 2017 at 14:30:44 UTC, A Guy With a Question wrote:If thats the case why not just throw a compiler error? D has a way explicitly not set it right? Through void...So if the intent is to find erroneous code right away, just throw a compiler error no?I would have expected 0 to be the default value. What's the logic behind having them being NaN by default?It gives you a runtime error (sort of) if you use an uninitialized variable. You ARE supposed to explicitly initialize variables to your own values in D. The automatic init is to make errors stand out more consistently if you don't do this as opposed to being random. So pointers are initialized to null - an invalid value that stands out if you try to use it. chars get \xFF - again, invalid that will throw if you try to utf decode it. Floats get NaN which is as close to invalid as they get. ints happen to get 0 not to be convenient, but because there is no clearly-invalid int value so something had to be chosen, and 0 was just easy to implement....
Nov 24 2017
On Friday, November 24, 2017 20:43:14 A Guy With a Question via Digitalmars- d-learn wrote:On Friday, 24 November 2017 at 14:43:24 UTC, Adam D. Ruppe wrote:That requires data flow analysis, which the compiler doesn't do a lot of, because it can be complicated. It also tends to result in the compiler giving warnings or errors in cases where it's not actually true that the variable is used before it's given a value, because it can't do it perfectly. There was a recent discussion on this in the main newsgroup with regards to guaranteeing with a pointer or reference was initialized to something other than null. Also, when you start having stuff like arrays, having a default initializer is a big boon, since then all of the elements have a default value. It's going to work even worse to try and have the compiler detect when you've properly initialized every element in an array than have it detect when you've properly initialized just a variable. And stuff like the out attribute relies on there being a default initializer. Just all around, having default initializers for types in general makes things cleaner and less error-prone. And NaN math is something that's built into CPU. Operations other than default initialization can result in a floating point value being NaN. So, if you're looking to have NaN not be a thing for floating point values, then you're out of luck. And Walter is a big fan of NaN being a thing, since when you hit it, you know that you've found a bug, and tracking it down tends to be fairly straightforward, which is not the case with many other types of bugs. - Jonathan M DavisOn Friday, 24 November 2017 at 14:30:44 UTC, A Guy With a Question wrote:If thats the case why not just throw a compiler error? D has a way explicitly not set it right? Through void...So if the intent is to find erroneous code right away, just throw a compiler error no?I would have expected 0 to be the default value. What's the logic behind having them being NaN by default?It gives you a runtime error (sort of) if you use an uninitialized variable. You ARE supposed to explicitly initialize variables to your own values in D. The automatic init is to make errors stand out more consistently if you don't do this as opposed to being random. So pointers are initialized to null - an invalid value that stands out if you try to use it. chars get \xFF - again, invalid that will throw if you try to utf decode it. Floats get NaN which is as close to invalid as they get. ints happen to get 0 not to be convenient, but because there is no clearly-invalid int value so something had to be chosen, and 0 was just easy to implement....
Nov 24 2017
On Friday, 24 November 2017 at 22:38:49 UTC, Jonathan M Davis wrote:On Friday, November 24, 2017 20:43:14 A Guy With a Question via Digitalmars- d-learn wrote:I think he means just spew an error if a float is declared but not explicitly initialised... Whats the problem with... float foo; // compiler error "floats must be explicitly initialised" float foo = float.nan; // old behaviour. I mean at the end of the day, that would turn a run time error into a compile time error which is a good thing isnt it?On Friday, 24 November 2017 at 14:43:24 UTC, Adam D. RuppeThat requires data flow analysis, which the compiler doesn't do a lot of, because it can be complicated. It also tends to result in the compiler giving warnings or errors in cases where it's not actually true that the variable is used before it's given a value, because it can't do it perfectly. There was a recent discussion on this in the main newsgroup with regards to guaranteeing with a pointer or reference was initialized to something other than null.
Nov 25 2017
On Saturday, 25 November 2017 at 09:39:15 UTC, Dave Jones wrote:On Friday, 24 November 2017 at 22:38:49 UTC, Jonathan M Davis wrote:That is exactly what I meant. I think most languages just choose to default it to something convenient, which is 0. C++ chooses not to default it for speed reasons. If D chooses it's defaults to make errors stick out, why not just error at declaration if they don't explicitly set it to something. Including void, which would give you C++ undefined behavior from what I've read so far.On Friday, November 24, 2017 20:43:14 A Guy With a Question via Digitalmars- d-learn wrote:I think he means just spew an error if a float is declared but not explicitly initialised... Whats the problem with... float foo; // compiler error "floats must be explicitly initialised" float foo = float.nan; // old behaviour. I mean at the end of the day, that would turn a run time error into a compile time error which is a good thing isnt it?On Friday, 24 November 2017 at 14:43:24 UTC, Adam D. RuppeThat requires data flow analysis, which the compiler doesn't do a lot of, because it can be complicated. It also tends to result in the compiler giving warnings or errors in cases where it's not actually true that the variable is used before it's given a value, because it can't do it perfectly. There was a recent discussion on this in the main newsgroup with regards to guaranteeing with a pointer or reference was initialized to something other than null.
Nov 25 2017
Nonetheless, my original question was answered. Thanks for the insights!
Nov 25 2017
On Saturday, 25 November 2017 at 16:16:52 UTC, A Guy With a Question wrote:If D chooses it's defaults to make errors stick out, why not just error at declaration if they don't explicitly set it to something.It technically did: https://dlang.org/spec/function.html#local-variables "It is an error to use a local variable without first assigning it a value. The implementation may not always be able to detect these cases. Other language compilers sometimes issue a warning for this, but since it is always a bug, it should be an error. " But that paragraph was never implemented (it is a bit easier said than done to actually detect given if conditions and stuff too, especially in the early days of D when the compiler didn't even make any effort to track such things, though it does now...). The compiler author took the easy way out of initializing them to invalid values instead. While it is more realistic to implement technically now than it was years ago when the current behavior got in, I think we're at the point now that so many people use it as a convenience thing on ints and nulls that there'd be hell to pay if the compiler actually started calling it an error :(
Nov 25 2017
On Saturday, 25 November 2017 at 22:13:43 UTC, Adam D. Ruppe wrote:On Saturday, 25 November 2017 at 16:16:52 UTC, A Guy With a Question wrote:Fair enough!If D chooses it's defaults to make errors stick out, why not just error at declaration if they don't explicitly set it to something.It technically did: https://dlang.org/spec/function.html#local-variables "It is an error to use a local variable without first assigning it a value. The implementation may not always be able to detect these cases. Other language compilers sometimes issue a warning for this, but since it is always a bug, it should be an error. " But that paragraph was never implemented (it is a bit easier said than done to actually detect given if conditions and stuff too, especially in the early days of D when the compiler didn't even make any effort to track such things, though it does now...). The compiler author took the easy way out of initializing them to invalid values instead. While it is more realistic to implement technically now than it was years ago when the current behavior got in, I think we're at the point now that so many people use it as a convenience thing on ints and nulls that there'd be hell to pay if the compiler actually started calling it an error :(
Nov 25 2017
On 11/25/17 5:13 PM, Adam D. Ruppe wrote:On Saturday, 25 November 2017 at 16:16:52 UTC, A Guy With a Question wrote:I rely on the default value initialization all the time! I don't know how that would jive with structs, since they are technically local variables, but usually are valid without initialization. What about AAs? Would you have to do = []? -SteveIf D chooses it's defaults to make errors stick out, why not just error at declaration if they don't explicitly set it to something.It technically did: https://dlang.org/spec/function.html#local-variables "It is an error to use a local variable without first assigning it a value. The implementation may not always be able to detect these cases. Other language compilers sometimes issue a warning for this, but since it is always a bug, it should be an error. " But that paragraph was never implemented (it is a bit easier said than done to actually detect given if conditions and stuff too, especially in the early days of D when the compiler didn't even make any effort to track such things, though it does now...). The compiler author took the easy way out of initializing them to invalid values instead. While it is more realistic to implement technically now than it was years ago when the current behavior got in, I think we're at the point now that so many people use it as a convenience thing on ints and nulls that there'd be hell to pay if the compiler actually started calling it an error :(
Nov 27 2017
On Monday, 27 November 2017 at 14:58:42 UTC, Steven Schveighoffer wrote:I rely on the default value initialization all the time! I don't know how that would jive with structs, since they are technically local variables, but usually are valid without initialization.Yes, indeed, me too. I like it now. But there might be a compromise that is still workable: let structs and ints (and bytes, short, etc) be exceptions and not issue an error there. But then conservatively check other types. If the compiler sees any read before any write, issue the error. Otherwise, keep the status quo. That's fit the spec and catch real bugs more often than false positives. Though, I'm in no ruse to see that implemented either, overall I am meh on it.What about AAs? Would you have to do = []?they could be an exception too, but you could do = null (= [] won't pass the type check lol)
Nov 27 2017
On Saturday, 25 November 2017 at 22:13:43 UTC, Adam D. Ruppe wrote:It technically did: https://dlang.org/spec/function.html#local-variables "It is an error to use a local variable without first assigning it a value. The implementation may not always be able to detect these cases. Other language compilers sometimes issue a warning for this, but since it is always a bug, it should be an error. " But that paragraph was never implemented (it is a bit easier said than done to actually detect given if conditions and stuff too, especially in the early days of D when the compiler didn't even make any effort to track such things, though it does now...). The compiler author took the easy way out of initializing them to invalid values instead.WOW!! I am shocked to learn this. All this time, I though it was a design oversight. I think I'm going to implement a feature gate to require explicit initialization. It would be better to be strict up front and relax it as flow control analysis becomes more mature. Mike
Nov 27 2017
On Monday, 27 November 2017 at 23:05:55 UTC, Michael V. Franklin wrote:I think I'm going to implement a feature gate to require explicit initialization. It would be better to be strict up front and relax it as flow control analysis becomes more mature.Well, I implemented it (https://github.com/dlang/dmd/pull/7375), but it's off to a pretty rocky start. Mike
Nov 28 2017
On Tuesday, 28 November 2017 at 20:00:53 UTC, Michael V. Franklin wrote:On Monday, 27 November 2017 at 23:05:55 UTC, Michael V. Franklin wrote:To be honest, I didn't actually expect anyone to act on my question. :D I was just more curious of the design decisions that were made.I think I'm going to implement a feature gate to require explicit initialization. It would be better to be strict up front and relax it as flow control analysis becomes more mature.Well, I implemented it (https://github.com/dlang/dmd/pull/7375), but it's off to a pretty rocky start. Mike
Nov 28 2017
On Wednesday, 29 November 2017 at 01:24:21 UTC, A Guy With a Question wrote:I was just more curious of the design decisions that were made.So am I. I'm trying to get to the heart of in the the PR comments. Mike
Nov 28 2017
On Wednesday, 29 November 2017 at 01:25:47 UTC, Michael V. Franklin wrote:On Wednesday, 29 November 2017 at 01:24:21 UTC, A Guy With a Question wrote:That's a lot less code than I would have thought to implement that. The comment about phobos was a good one. Just reading through it.I was just more curious of the design decisions that were made.So am I. I'm trying to get to the heart of in the the PR comments. Mike
Nov 28 2017
On Saturday, 25 November 2017 at 09:39:15 UTC, Dave Jones wrote:I mean at the end of the day, that would turn a run time error into a compile time error which is a good thing isnt it?Debatable in this case. Consider: string servicePhoneNumber; final switch (car.manufacturer) //an enumerated value. { case CarMaker.Audi: servicePhoneNumber = staff["Dorff Hans"].phone; //... break; case CarMaker.Skoda: servicePhoneNumber = staff["Telegin Svetlana"].phone; //... break; //more cases ... } Here it is arguably unnecessary typing if you had to manually set servicePhoneNumber to "" or something at start. And in case of structs it tends to be a verbose thing to manually set one to it's init value.
Nov 27 2017
On Monday, 27 November 2017 at 16:04:14 UTC, Dukc wrote:Debatable in this case. Consider: string servicePhoneNumber; final switch (car.manufacturer) //an enumerated value.Well, the compiler can see it is initialized before being read again later, so that *should* pass the check (at least conservatively- the spec is flexible enough to let the compiler not catch them all).
Nov 27 2017
On Friday, 24 November 2017 at 22:38:49 UTC, Jonathan M Davis wrote:That requires data flow analysis, which the compiler doesn't do a lot of, because it can be complicated.If dataflow is sufficient then it isn't all that complicated, you can implement generic dataflow using Monotone Frameworks: http://symbolaris.com/course/Compilers11/27-monframework.pdf But on the other hand, data flow might not be sufficient for what you want to do.And NaN math is something that's built into CPU. Operations other than default initialization can result in a floating point value being NaN.If you have turned on exceptions for signalling-NaNs then it makes sense. It doesn't make all that much sense for quiet NaNs.
Nov 25 2017
On Friday, 24 November 2017 at 14:30:44 UTC, A Guy With a Question wrote:I would have expected 0 to be the default value. What's the logic behind having them being NaN by default? https://dlang.org/spec/type.htmlhttp://www.drdobbs.com/cpp/nans-just-dont-get-no-respect/240005723
Nov 29 2017