RFC on range design for D2
Andrei Alexandrescu
SeeWebsiteForEmail at erdani.org
Mon Sep 8 17:37:41 PDT 2008
Denis Koroskin wrote:
> 1) There is a typo:
>
> // Copies a range to another
> void copy(R1, R2)(R1 src, R2 tgt)
> {
> while (!src.isEmpty)
> {
> tgt.putNext(r.getNext); // should be tgt.putNext(src.getNext);
> }
> }
Thanks! Fixed.
> 2) R.next and R.pop could have better names. I mean, they represent
> similar operations yet names are so different.
I agree. Next was a natural choice. I stole pop from Perl. Any symmetric
and short operation names would be welcome.
> 3) Walter mentioned that built-in array could be re-implemented using a
> pair of pointers instead of ptr+length. Will it ever get a green light?
> It fits range concept much better.
Walter told me to first implement my design, and if it works, he'll do
the change. Yes, it does fit ranges much better because the often-used
next and, um, pop will only touch one word instead of two.
> 4) We need some way of supporting dollar notation in user containers.
> The hack of using __dollar is bad (although it works).
It doesn't work for multiple dimensions. There should be an
opDollar(uint dim) that gives the library information on which argument
count it occured in. Consider:
auto x = matrix[$-1, $-1];
Here the dollar's occurrences have different meanings. A good start
would be to expand the above into:
auto x = matrix[matrix.opDollar(0)-1, matrix.opDollar(1)-1];
> 5) I don't quite like names left and right! :) I think they should
> represent limits (pointers to begin and end, in case of array) rather
> that values. In this case, built-in arrays could be implemented as follows:
>
> struct Array(T)
> {
> T* left;
> T* right;
> size_t length() { return right-left; }
> ref T opIndex(size_t index) { return left[index]; }
> // etc
> }
>
> The rationale behind having access to range limits is to allow
> operations on them. For example,
> R.left-=n;
I disagree. Defining operations on range limits opens a box that would
make Pandora jealous:
1. What is the type of left in general? Um, let's define Iterator!(R)
for each range R.
2. What are the primitives of an iterator? Well, -= sounds good. How do
you check it for correctness? In fact, how do you check any operation of
a naked iterator for correctness?
3. I want to play with some data. What should I use here, ranges or
iterators? ...
Much of the smarts of the range design is that it gets away WITHOUT
having to answer embarrassing questions such as the above. Ranges are
rock-solid, and part of them being rock-solid is that they expose enough
primitives to be complete, but at the same time do not expose dangerous
internals.
> could be used instead of
> foreach(i; 0..n) {
> R.pop();
> }
>
> which is more efficient in many cases.
Stop right there. That's not a primitive. It is an algorithm that gets
implemented in terms of a primitive. I disagree that such an algorithm
is an operator and does not have a name such as popN.
> Other that that - great, I like it.
Thanks for your comments.
Andrei
More information about the Digitalmars-d-announce
mailing list