April 14, 2012
Jerome BENOIT wrote:
> Why would a compiler set `real' to 0.0 rather then 1.0, Pi, .... ?

Because 0.0 is the "lowest" (smallest, starting point, etc..) numerical value. Pi is the corner case and obviously has to be explicitly set.

If you want to take this further, chars could even be initialized to spaces or newlines or something similar. Pointers/references need to be defaulted to null because they absolutely must equal an explicit value before use. Value types don't share this limitation.

> The more convenient default set certainly depends on the underlying mathematics,
> and a compiler  cannot (yet) understand the encoded mathematics.
> NaN is certainly the certainly the very choice as whatever the involved mathematics,
> they will blow up sooner or later. And, from a practical point of view, blowing up is easy to trace.

Zero is just as easy for the runtime/compiler to default to; and bugs can be introduce anywhere in the code, not just definition. We have good ways of catching these bugs in D with unittests already.
April 14, 2012
On Saturday, 14 April 2012 at 10:38:45 UTC, Silveri wrote:
> On Saturday, 14 April 2012 at 07:52:51 UTC, F i L wrote:
>> On Saturday, 14 April 2012 at 06:43:11 UTC, Manfred Nowak wrote:
>>> F i L wrote:
>>>
>>> 4) use hardware signalling to overcome some of the limitations
>>> impressed by 3).
>>
>> 4) I have no idea what you just said... :)
>
> On Saturday, 14 April 2012 at 07:58:44 UTC, F i L wrote:
>> That's interesting, but what effect does appending an invalid char to a valid one have? Does the resulting string end up being "NaS" (Not a String)? Cause if not, I'm not sure that's a fair comparison.
>
> The initialization values chosen are also determined by the underlying hardware implementation of the type. Signalling NANs (http://en.wikipedia.org/wiki/NaN#Signaling_NaN) can be used with floats because they are implemented by the CPU, but in the case of integers or strings their aren't really equivalent values.

I'm sure the hardware can just as easily signal zeros.


> On Saturday, 14 April 2012 at 07:45:58 UTC, F i L wrote:
>> My original post was inspired by me showing my D code to another C# guy earlier, and coming up with poor explanations as to why floats where required to be defaulted in my math lib. His reaction what along the lines of my first post.
>
> I think the correct mindset when working in D is to think that "all variables should be initialized" and if you get incorrect calculations with zero values, division by zero errors or nan errors the most likely mistake is often that this guideline was not followed.

Like I said before, this is backwards thinking. At the end of the day, you _can_ use default values in D. Given that ints are defaulted to usable values, FP Values should be as well for the sake of consistency and convenience.

You can't force new D programmers to follow a 'guidline' no matter how loudly the documentation shouts it (which is barely does at this point), so said guideline is not a dependable practice all D will follow (unless it's statically enforced)... nor _should_ the learning curve be steepened by enforcing awareness of this idiosyncrasy.

The correct mindset from the compilers perspective should be: "people create variables to use them. What do they want if they didn't specify a value?"

therefor our mindset can be: "I defined a variable to use. Should be zero so I don't need to set it."
April 14, 2012
dennis luehring wrote:
> what does make float default to 0.0 better - does it just feel better?

Not just. It's consistent with Int types, therefor easier for newbs to pick up since all numeric value types behave the same.

I even think char should default to a usable value as well. Most likely a space character. But that's another point.

April 14, 2012
On Saturday, 14 April 2012 at 12:48:01 UTC, Andrej Mitrovic wrote:
> On 4/14/12, bearophile <bearophileHUGS@lycos.com> wrote:
>> Having a variable not initialized is a common source of bugs.
>
> I'm going to argue that this was true for C/C++ but is much less true
> for D. One benefit of having integrals initialized to 0 is that you
> now have a defined default that you can rely on (just as you can rely
> on pointers being null by default). Personally I find this to be a big
> win in productivity. If the language/runtime does something defined
> for me then I can focus on more important things.

Amen! This is exactly what I'm trying to get at. The compiler provides defaults as a convince feature (mostly) so that there's no garbage and so values are reliable. It's incredibly inconvenient at that point to have to remember to always explicitly init one specific type..

This feels very natural in C#.
April 14, 2012
On 4/14/12, F i L <witte2008@gmail.com> wrote:
> This is exactly what I'm trying to get at.

Anyway it's not all bad news since we can use a workaround:

struct Float {
    float payload = 0.0;
    alias payload this;
}

void main() {
    Float x;  // acts as a float, is initialized to 0.0
}

Not pretty, but it comes in handy.
April 14, 2012

On 14/04/12 16:47, F i L wrote:
> Jerome BENOIT wrote:
>> Why would a compiler set `real' to 0.0 rather then 1.0, Pi, .... ?
>
> Because 0.0 is the "lowest" (smallest, starting point, etc..)

quid -infinity ?

numerical value. Pi is the corner case and obviously has to be explicitly set.
>
> If you want to take this further, chars could even be initialized to spaces or newlines or something similar. Pointers/references need to be defaulted to null because they absolutely must equal an explicit value before use. Value types don't share this limitation.
>

CHAR set are bounded, `real' are not.


>> The more convenient default set certainly depends on the underlying mathematics,
>> and a compiler cannot (yet) understand the encoded mathematics.
>> NaN is certainly the certainly the very choice as whatever the involved mathematics,
>> they will blow up sooner or later. And, from a practical point of view, blowing up is easy to trace.
>
> Zero is just as easy for the runtime/compiler to default to;

Fortran age is over.
D compiler contains a lot of features that are not easy to set up by the compiler BUT meant for easing coding.


 and bugs can be introduce anywhere in the code, not just definition.

so the NaN approach discard one source of error.

 We have good ways of catching these bugs in D with unittests already.

Zero may give a value that sounds reasonable, NaN will give a NaN value ... which is not reasonable: this is NaN blow up and it can been seen right the way.

Note that the NaN approach is used in some numerical libraries as CLN.

April 14, 2012
On Saturday, 14 April 2012 at 15:44:46 UTC, Jerome BENOIT wrote:
>
>
> On 14/04/12 16:47, F i L wrote:
>> Jerome BENOIT wrote:
>>> Why would a compiler set `real' to 0.0 rather then 1.0, Pi, .... ?
>>
>> Because 0.0 is the "lowest" (smallest, starting point, etc..)
>
> quid -infinity ?

The concept of zero is less meaningful than -infinity. Zero is the logical starting place because zero represents nothing (mathematically), which is inline with how pointers behave (only applicable to memory, not scale).


> numerical value. Pi is the corner case and obviously has to be explicitly set.
>>
>> If you want to take this further, chars could even be initialized to spaces or newlines or something similar. Pointers/references need to be defaulted to null because they absolutely must equal an explicit value before use. Value types don't share this limitation.
>>
>
> CHAR set are bounded, `real' are not.

Good point, I'm not so convinced char should default to " ". I think there are arguments either way, I haven't given it much thought.


>>> The more convenient default set certainly depends on the underlying mathematics,
>>> and a compiler cannot (yet) understand the encoded mathematics.
>>> NaN is certainly the certainly the very choice as whatever the involved mathematics,
>>> they will blow up sooner or later. And, from a practical point of view, blowing up is easy to trace.
>>
>> Zero is just as easy for the runtime/compiler to default to;
>
> Fortran age is over.
> D compiler contains a lot of features that are not easy to set up by the compiler BUT meant for easing coding.
>
>
>  and bugs can be introduce anywhere in the code, not just definition.
>
> so the NaN approach discard one source of error.

Sure, the question then becomes "does catching bugs introduced by inaccurately defining a variable outweigh the price of inconsistency and learning curve." My opinion is No, expected behavior is more important. Especially when I'm not sure I've ever heard of someone in C# having bugs that would have been helped by defaulting to NaN. I mean really, how does:

    float x; // NaN
    ...
    x = incorrectValue;
    ...
    foo(x); // first time x is used

differ from:

    float x = incorrectValue;
    ...
    foo(x);

in any meaning full way? Except that in this one case:

    float x; // NaN
    ...
    foo(x); // uses x, resulting in NaNs
    ...
    x = foo(x); // sets after first time x is used

you'll get a "more meaningful" error message, which, assuming you didn't just write a ton of FP code, you'd be able to trace to it's source faster.

It just isn't enough to justify defaulting to NaN, IMO. I even think the process of hunting down bugs is more straight forward when defaulting to zero, because every numerical bug is pursued the same way, regardless of type. You don't have to remember that FP specifically causes this issues in only some cases.
April 14, 2012
On Saturday, 14 April 2012 at 15:35:13 UTC, Andrej Mitrovic wrote:
> On 4/14/12, F i L <witte2008@gmail.com> wrote:
>> This is exactly what I'm trying to get at.
>
> Anyway it's not all bad news since we can use a workaround:
>
> struct Float {
>     float payload = 0.0;
>     alias payload this;
> }
>
> void main() {
>     Float x;  // acts as a float, is initialized to 0.0
> }
>
> Not pretty, but it comes in handy.

Lol, that's kinda an interesting idea:

    struct var(T, T def) {
        T payload = def;
        alias payload this;
    }

    alias var!(float,  0.0f) Float;
    alias var!(double, 0.0)  Double;
    alias var!(real,   0.0)  Real;
    alias var!(char,   ' ')  Char;

    void main() {
        Float f;
        assert(f == 0.0f);
    }

a Hack though, since it doesn't work with 'auto'. I still think it should be the other way around, and this should be used to Default to NaN.
April 14, 2012
On 4/14/12, F i L <witte2008@gmail.com> wrote:
> a Hack though, since it doesn't work with 'auto'.

What do you mean?
April 14, 2012
On Saturday, 14 April 2012 at 17:30:19 UTC, Andrej Mitrovic wrote:
> On 4/14/12, F i L <witte2008@gmail.com> wrote:
>> a Hack though, since it doesn't work with 'auto'.
>
> What do you mean?

Only that:

    auto f = 1.0f; // is float not Float