D's greatest mistakes
Michel Fortin
michel.fortin at michelf.com
Mon Nov 29 17:52:48 PST 2010
On 2010-11-29 14:03:27 -0500, Andrei Alexandrescu
<SeeWebsiteForEmail at erdani.org> said:
>> For instance, here's a tricky question: should Unqual!(const C) give you
>> a const(C), a Rebindable!(const C), or simply C?
>
> C.
>
>> Now, what should
>> const(Unqual!(immutable C)) give you?
>
> const(C).
As I thought.
Now consider this generic code that uses Unqual:
T[] giveMeASortedArray(alias Predicate, T)(T[] t) {
// creating new array of the same length but with assignable elements
auto copy = new Unqual!(typeof(t[0]))[t.length];
// using a loop because copy[] = t[] doesn't enforce const properly!
foreach (index, value; t)
copy[index] = value;
// sorting the copy
sort!(Predicate)(copy);
return copy;
}
The above algorithm will work for types like const(int*), but it breaks
if T is const(C) and C is a class. So it seems we'll need a special
cases for generic algorithms to work for classes. That's what I meant
when I say Rebindable is a fragile solution. It works in most cases,
but it breaks in some others, mostly when you want to be generic.
So here's the challenge for you Andrei: find a way to make this code
work without special-casing things for classes. The
"giveMeASortedArray" function needs to return a new array containing
all the elements of the original array, sorted according to the
predicate. Here's my test case (the last line is the tricky one):
int*[] a = giveMeASortedArray!("a < b")(new int*[12]);
Object[] b = giveMeASortedArray!("a < b")(new Object[12]);
const(int*)[] c = giveMeASortedArray!("a < b")(new const(int*)[12]);
const(Object)[] d = giveMeASortedArray!("a < b")(new const(Object)[12]);
Good luck. It's doable using convoluted means and special-casing things
for classes, but that'll just prove my point that Rebindable isn't a
good solution.
--
Michel Fortin
michel.fortin at michelf.com
http://michelf.com/
More information about the Digitalmars-d
mailing list