RFC on range design for D2

Sergey Gromov snake.scaly at gmail.com
Wed Sep 10 04:21:41 PDT 2008


Andrei Alexandrescu <SeeWebsiteForEmail at erdani.org> wrote:
> Sergey Gromov wrote:
> > Andrei Alexandrescu <SeeWebsiteForEmail at erdani.org> wrote:
> >> A better design would be to define collections that own their contents. 
> >> For example:
> >>
> >> Array!(int) a(100);
> >>
> >> This time a does own the underlying array. You'd be able to get ranges 
> >> all over it:
> >>
> >> int[] b = a.all;
> > 
> > I really don't like to have basic language constructs implemented as 
> > templates.  It's like Tuple!() which is sorta basic type but requires 
> > template trickery to really work with it.
> 
> Well I guess we disagree on a number of issues here. The problem with
> "sorta basic" types is that the list could go on forever. I'd rather use
> a language that allows creation of good types from a small core, instead
> of one that tries to supplant all sorta basic types it could think of.

I think I've got your point here.  D is not Python, it shouldn't do 
anything high-level in the core.  The notion of range is sufficient to 
iterate through anything, core (namely foreach) doesn't need to be aware 
of the collections themselves.

Though I'm not fully convinced.  It's always good to have good defaults.  
So that you could quickly throw things together, and attend to details 
later.  So that you could write

string[string] dic;
foreach(k, v; dic) whatever;

Can I do this with your Array!()?  Or should I always use all() even 
though the Array!() is plain linear and obvious?

> > auto a = new File("name");
> > auto b = new TreeSet!(char);
> > 
> > foreach(ch; a)
> >   b.insert(ch);
> > 
> > foreach(ch; b)
> >     writeln("unique char ", ch);
> > 
> > Here is the problem.  First foreach() naturally and expectedly changes 
> > the state of an object a.  Second foreach() naturally and expectedly 
> > does not make changes to object b.
> > 
> > Solution:
> > 
> > File is an Input range in your notion.  It supports isEmpty() and 
> > getNext(), it is non-copyable (but, note, referenceable).
> 
> You left a crucial detail out. What does getNext() return?

Something.  Documented.  I'd be happy with string, that is, line by line 
iteration.  It's nice for text dumping, simple configurations, simple 
internet protocols like POP and FTP, user interaction.  You see, some 
useful default.  The File could also provide byte range bytes() and 
dchar range chars() and whatever the author considered feasible.

Note that I wasn't convincing you to change stdio design.  My choice of 
class names was bad.  I should have used MyFile instead of File, meaning 
some user class with user functionality.

> In the new std.stdio design, a File is preoccupied with opening,
> closing, and transferring data for the underlying file. On top of it
> several input ranges can be constructed - that read lines, blocks, parse
> text, format text, and so on. (One thing I want is to allow
> std.algorithm to work with I/O easily and naturally.)

OK, you like this design, no problem.  Better even.  Your File is 
naturally iterable over its bytes.  Any low-level file is, anybody knows 
that.  I can see no reason to deny foreach() over a file.

> > foreach() checks if a passed object implements opSlice() so that it can 
> > iterate non-destructively. If no opSlice() is provided, it falls back to 
> > getNext().


More information about the Digitalmars-d-announce mailing list