we need a std.algorithm.equalRecurse(T1,T2)(T1 a, T2 b) that compares recursively a and b;

its behavior should be:

if opEqual is defined, call it
else, if its a range, call std.algorithm.equal (ie compare nb elements, then each element for equality) else, if it's a class/struct, make sure types are same and call it recursively on each field.
else if it's a numerical type, call "=="
else (is there an else?)

just as std.algorithm.equal, we should have equalRecurse([1],[1.0]);

Currently, "==" works in a non-intuitive way, breaking principle of least surprise:
----
struct A{       int[]b=[1]; }
void main(){
        auto a1=A();
        auto a2=A();
        assert(a1!=a2);
}
----
we should have:
assert(equalRecurse(a1,a2));

What are your thoughts on those:

A)
Can we just extend std.algorithm.equal (which only works on ranges) to arbitrary types instead of introducing a new function equalRecurse ?

B)
Should "==" / opEqual behave like that (but it might be too late to change)?

C)
in the example above, why assert(a1!=a2); but assert(A.init==A.init); ?

D)
Additionally, we would need a sister function firstDifference(T1, T2)(T1 a, T2 b) that finds the first difference among a and b. How to represent that in a generic way is not clear (should for example, find a particular field being different, etc). How about a string output:
assert(firstDifference([1,2,3],[1,2,3]) == null);
assert(firstDifference([1,2,3],[1,3]) == "a.length");
assert(firstDifference([1,2,3],[1,4,3]) == "a[1]");
A a1; A a2; a1.x=1; a2.x=2;
assert(firstDifference(a1,a2) == "a.x");
assert(firstDifference(a1,void) == "typeid(a)");

Both would be very useful for debugging.

Reply via email to