Issue 3789 is an enhancement request, I think it fixes one small but quite 
important problem in D design. The situation is shown by this simple code:


struct String {
    char[] data;
}
void main () {
    auto foo = String("foo".dup);
    auto bar = String("foo".dup);
    assert(bar !is foo, "structs aren't the same bit-wise");
    assert(bar == foo, "oops structs aren't equal");
}



The D Zen says D is designed to be safe on default and to perform unsafe (and 
faster) things on request. Not comparing the strings as strings in the 
following code breaks the Principle of least astonishment, so breaks that rule.

An acceptable alternative to fixing Bug 3789 is statically disallowing the 
equal operator (==) in such cases (or even in all cases).

D has the "is" for the situations where you want to perform bitwise comparison, 
for structs too. For the other situations where I use "==" among struts, I want 
it do the right thing, like comparing its contained strings correctly instead 
of arbitrarily deciding to use bitwise comparison of the sub-struct that 
represents the string.

There is already a patch for this, from the extra-good Kenji Hara:
https://github.com/D-Programming-Language/dmd/pull/387

Making "==" work as "is" for structs means using an operator for the purpose of 
the other operator, and it has caused some bugs in my code. And it will cause 
bugs in D code to come.


Another example, reduced/modified from a real bug in a program of mine:


import std.stdio;
struct Foo {
    int x;
    string s;
}
void main () {
    int[Foo] aa;
    aa[Foo(10, "hello")] = 1;
    string hel = "hel";
    aa[Foo(10, hel ~ "lo")] = 2;
    writeln(aa);
}


Here D defines a hashing for the Foo struct, but it uses the standard "==" to 
compare the struct keys. So the output is this, that I believe is what almost 
no one will ever want:

[Foo(10, "hello"):1, Foo(10, "hello"):2]

Bye,
bearophile

Reply via email to