RFC on range design for D2

Robert Jacques sandford at jhu.edu
Mon Sep 8 19:22:04 PDT 2008


On Mon, 08 Sep 2008 20:24:27 -0400, Andrei Alexandrescu  
<SeeWebsiteForEmail at erdani.org> wrote:

> About the "collection should be a range itself" mantra, I've had a  
> micro-epiphany. Since D's slices so nicely model at the same time arrays  
> and their ranges, it is very seductive to think of carrying that to  
> other collection types. But I got disabused of that notion as soon as I  
> wanted to define a less simple data structure. Consider a matrix:
>
> auto a = BlockMatrix!(float, 3)(100, 200, 300);
>
> defines a block contiguous matrix of three dimensions with the  
> respective sizes. Now a should be the matrix AND its range at the same  
> time. But what's "the range" of a matrix? Oops. As soon as you start to  
> think of it, so many darn ranges come to mind.
>
> * flat: all elements in one shot in an arbitrary order
>
> * dimension-wise: iterate over a given dimension
>
> * subspace: iterate over a "slice" of the matrix with fewer dimensions
>
> * diagonal: scan the matrix from one corner to the opposite corner
>
> I guess there are some more. So before long I realized that the most  
> gainful design is this:
>
> a) A matrix owns its stuff and is preoccupied with storage internals,  
> allocation, and the such.
>
> b) The matrix defines as many range types as it wants.
>
> c) Users use the ranges.
>
> For example:
>
> foreach (ref e; a.flat) e *= 1.1;
> foreach (row; a.dim(0)) row[0, 0] = 0;
> foreach (col; a.dim(1)) col[1, 1] *= 5;

I'd recommend a more clear cut example. Three of the ranges are very well  
defined in array languages and libraries. Essentially a slice of a matrix  
is another matrix that may have less or more dimensions and therefore may  
be a collection in addition to a range. The dimension-wise range is the  
only operation which is more complex, due to the type and dimensions of  
the returned array changing float[x,y,z] -> float[x,y][z]. And the main  
argument is that a float[x,y][z] is large, slow to create and unwanted, so  
a separate range/generator is better (Also note a generator can provide  
implicit the head const, tail mutable nature of the range). Even given  
this, it doesn't contratict the "collection should be a range itself"  
mantra, since there is a very well defined range which encompasses the  
data, its just that some ranges are more optimal if they're only views,  
and not a root collection.


More information about the Digitalmars-d-announce mailing list