Andrei Alexandrescu wrote:
grauzone wrote:
Don wrote:
Christopher Wright wrote:
grauzone wrote:
You're not testing for types, you're testing if it compiles. Inside
the tested block of code, all sorts of things could go wrong. You
can't know if is(typeof(...)) really did what you wanted, or if
something broke.
You're testing, "is everything inside that OK?". If you want to know
WHY it's wrong, you'd better make sure you're testing something simple.
Andrei's range lib uses it more in a way "does this type support this
and that range interface?". Example:
http://dsource.org/projects/phobos/browser/trunk/phobos/std/range.d#L58
Then different isXxxRange are used by higher-order ranges in defining
refined interfaces depending on the interfaces offered by their inputs.
I fail to see how that's terrible. I am very happy D has that feature -
no other statically-typed language has it, and it can be used to great
effect. Look e.g. at Chain:
http://dsource.org/projects/phobos/browser/trunk/phobos/std/range.d#L799
There, the uses of static if (is(...)) allow Chain to define as capable
an interface as its inputs allow.
Andrei
I really like Andrei's range library, I use it all the time when I need
to pass slices of generic types around, it really is more convenient
than a pair of iterators.
The way I see ranges is as a form of interface without being bound to
classes; its the only way to make structs and D arrays pass the
isXxxRange traits.
The prototypes for using ranges then just go from:
void dosomething(T)(IForwardRange!T range) {}
to
void dosomething(Range)(Range range) if(isForwardRange!Range) {}
and it means the same thing, but you can't send a string to IForwardRange.