On Tuesday, 27 May 2014 at 19:39:23 UTC, Idan Arye wrote:
Hashing the function body is not enough - you must also
consider the closure!
template Template(alias func){
bool Template=func();
}
void foo(){
int a;
writeln(Template!(()=>is(typeof(a) : char))); //prints
"false"
}
void bar(){
char a;
writeln(Template!(()=>is(typeof(a) : char))); //prints
"true"
}
If two delegates must have exactly the same scope, the
usefulness of the hashing will be quite limited, but in many
cases the same lambda can be declared in different scopes and
still be the same. It all depends on how the lambda uses the
closure - and checking this will be quite hard to implement...
If I remember correctly, the main use-case of comparing lambda
functions was for cases like this:
auto rb1 = make!(RedBlackTree!(int, (a, b) => a < b))([4, 2, 3,
1]);
auto rb2 = make!(RedBlackTree!(int, (a, b) => a < b))([4, 2, 3,
1]);
assert(is(typeof(rb1) == typeof(rb2))); //FAIL
assert(rb1 == rb2); //FAIL
Note that this code passes if you define a top-level function
"less" and pass it to make. Functions don't have function
pointers, only delegates, so as a first step we could implement
hashing for functions, which don't have to deal with all this
context pointer business. Also, couldn't you achieve the same for
delegates if you specify that only @pure @nogc delegates can be
compared?