September 12, 2008
Andrei Alexandrescu wrote:
> In wake of the many excellent comments and suggestions made here, I made one more pass through the draft proposal for ranges.
> 
> http://ssli.ee.washington.edu/~aalexand/d/tmp/std_range.html
> 
> There are some comments in red illustrating some uncertainties (not all), and the names of the primitives have been updated. Bicycle shed galore! But don't forget to comment on the reactor as well :o).
> 
> 
> Andrei

Just a little typo, in the "Output range" example:

// Copies a range to another
void copy(R1, R2)(R1 src, R2 tgt)
{
    for (; !src.done; src.head)
    {
        tgt.put(src.head);
    }
}

the for increment should be src.next
September 12, 2008
Ary Borenszweig wrote:
> Andrei Alexandrescu wrote:
>> In wake of the many excellent comments and suggestions made here, I made one more pass through the draft proposal for ranges.
>>
>> http://ssli.ee.washington.edu/~aalexand/d/tmp/std_range.html
>>
>> There are some comments in red illustrating some uncertainties (not all), and the names of the primitives have been updated. Bicycle shed galore! But don't forget to comment on the reactor as well :o).
>>
>>
>> Andrei
> 
> Just a little typo, in the "Output range" example:
> 
> // Copies a range to another
> void copy(R1, R2)(R1 src, R2 tgt)
> {
>     for (; !src.done; src.head)
>     {
>         tgt.put(src.head);
>     }
> }
> 
> the for increment should be src.next

Fixed, thanks Ary.

Andrei
September 12, 2008
Andrei Alexandrescu Wrote:

> Pablo Ripolles wrote:
> > Andrei Alexandrescu Wrote:
> > 
> >> In wake of the many excellent comments and suggestions made here, I made one more pass through the draft proposal for ranges.
> >>
> >> http://ssli.ee.washington.edu/~aalexand/d/tmp/std_range.html
> >>
> >> There are some comments in red illustrating some uncertainties (not all), and the names of the primitives have been updated. Bicycle shed galore! But don't forget to comment on the reactor as well :o).
> >>
> >>
> >> Andrei
> > 
> > 
> > Well, it looks prety clean! :D
> > 
> > However, I'm not completely sure I like these "head" and "toe" names selection.  It projects to much on it, doesn't it?  couldn't it be more neutral?  perhaps more conceptual?  I haven't been able to read the last days' comments... but my last impressions were that this "head" was not the best choice.
> > 
> > If "head" is the header item, why not call it "header"?
> > 
> > If ''toe" is the last item, why not call it "last"?
> > 
> > Other comment goes for the "done" property, for the seek of consistence shouldn't it better be named "isDone"?
> > 
> > Cheers!
> 
> Thanks. One problem in coding with first and last was that sometimes the code looks unnatural, especially when your range exposes a few more functions. In a stream parser, dealing with the "first" element is not the most natural way to think of it. But I agree that first and last are definitely palatable and natural most of the time. But then again, shouldn't any design have the inevitable cutesy that makes it memorable? :o)
> 
> Andrei

Well, in the first place thanks to you!  I really enjoy this enthusiastic attitude.

About "first", well, I didn't mentioned "first" as an alternative to "head" but "header" which is not necessarily an animal-like characteristic.  Anyway, "head" is definitely more poly-meaning than "toe"!!!!  I definitely would look for neutral alternative...

What about "isDone"?

And yes, to have a personality in the naming is nice but I guess that in this case seems too concrete, anthropocentric, I don't know, what the heck! even "tail" is semantically wider!

Keep this great interaction! Thanks!


September 12, 2008
Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
> In wake of the many excellent comments and suggestions made here, I made one more pass through the draft proposal for ranges.
> 
> http://ssli.ee.washington.edu/~aalexand/d/tmp/std_range.html
> 
> There are some comments in red illustrating some uncertainties (not all), and the names of the primitives have been updated. Bicycle shed galore! But don't forget to comment on the reactor as well :o).

I've got a heap of virtual sticky notes all over my monitor while reading the edited version, so here they are.

*)
done/next/head thing got even more confusing.  Range is not a process,
you cannot be done with it.  If you call a spade a spade, then done() is
actually a safe, guarded prefetch, head is, well, sort of what it claims
to be, and next() just relaxes done's guard.

The look ahead/fetch next approach was much more intuitive.  I don't understand why you dropped it.  I remember you saying that Bill convinced you it was wrong but I either missed the arguments themselves or hadn't understood them.

*)
How do you enforce noncopyable/release semantics over a range?  I don't
think D got any means for that.  Also if an input range is a class
passed by reference, will you allow it?

*)
before() is valid for a single-linked list, forward iterators should
support it.

*)
You've replaced tail with toe because people may think tail could
contain many elements.  But it doesn't pair well with head, and besides,
if I split a list in the middle I'd call the halves a head and a tail
which form a logical pair.  Maybe you consider tip-toe, or top-toe, from
the top of my head? ;)

*)
A typo: in Output range sample:
	for (; !src.done; src.head)
should be
	for (; !src.done; src.next)

*)
next() is specified to return a value, but reduce() is not.  This is
probably a typo.  I'd prefer them both be implemented as (done(), head)
and (reduce(), toe) respectively, but I don't know what your intention
was.

*)
Still uncertain support for shrink-on-read, no support for shrink-on-
write and slicing forward and bidirectional ranges.  Are they going into
a library?
September 12, 2008
On Fri, Sep 12, 2008 at 2:44 PM, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
> In wake of the many excellent comments and suggestions made here, I made one more pass through the draft proposal for ranges.
>
> http://ssli.ee.washington.edu/~aalexand/d/tmp/std_range.html
>
> There are some comments in red illustrating some uncertainties (not all), and the names of the primitives have been updated. Bicycle shed galore! But don't forget to comment on the reactor as well :o).
>

Looking better!

I disagree with this:
"""
User code may pair iterators wrongly to create meaningless ranges. For
example, given collections a and b of the same type, a.begin to
b.begin makes no sense as a range, yet both the compiler and the
runtime are hard-pressed in rejecting such mistakes. Such problems are
often (though not always) avoided if range is the primitive.
"""

You can just as easily create nonsensical ranges using before() and
after().  And I don't recall ever making the mistake of mixing up one
container's begin() with another's end().

I disagree here too:
"""
A bidirectional range models the natural way of iterating a doubly-linked list.
"""
It maybe provides an efficient way to implement many algorithms on a
doubly linked list.  But to say it implements the natural way of
iterating one is a big stretch.

I was about to argue that "head" should be "value" and "toe" should be "tvalue" on the grounds that most of the time iteration with a range going to be all about the head.  For all intents and purposes it *is* the current value.  Another benefit is that the terminology of ".value" generalizes to plain iterators well.  And it may be useful for users to create iterators that support some but not all of the range interface (like .value and .next).  The name .value doesn't work for the random access concept so well, but if you are using the random access range like a forward range it does, and if you aren't using it like a forward range,  then you'd use r[0] anyway instead of r.value.

However, that was mainly motivated by the feeling that if we ever do have iterators, that having to make the dereference op be .head would look fatally silly.  But I think eventually if you get out of the iterator mindset, and think of ranges as everything, then it's not so silly to describe an iterator as a poor castrated half-range that knows where its head is, where it's next is, but isn't so sure about the rest.  So I think I can live with .head.  Even for iterators if we end up having them.

But I do have some suggestions nonetheless!  Marked with ==> below.

-- Universal --
r.done
r.init

--- Input : Universal ---
e=r.head
e=r.next
r1=r.release  ==> r.transfer?  Release sounds like ref counting (e.g. in COM)
                          Also seems like r.transfer(r1) could make
implementation more efficient.
                          Or perhaps make it a .swap like STL.  Maybe
you have something against .swap?

-- Output : Universal --
r.put(e)

-- Forward : Input, (optional) Output  --
r1 = r
r.head = e
t=r.after(s)

-- Bidirectional : Forward --
e = r.toe
r.toe = e
r.reduce           ==> r.retreat  -- aka "pull back"
t = r.before(s)

-- Random access : Bidirectional --
l = r.length
e = r[n]
r[n] = e
r1 = r[n1..n2]
------------

Just those two!

--bb
September 12, 2008
"Andrei Alexandrescu" wrote
> In wake of the many excellent comments and suggestions made here, I made one more pass through the draft proposal for ranges.
>
> http://ssli.ee.washington.edu/~aalexand/d/tmp/std_range.html
>
> There are some comments in red illustrating some uncertainties (not all), and the names of the primitives have been updated. Bicycle shed galore! But don't forget to comment on the reactor as well :o).

You know my position ;)  But here are some things:

1. I like the new names of things much better.  This is a much prettier bicycle shed :)  And in this case, I think the bicycle shed is a little closer to the heart of the design than the nuclear reactor.  Maybe the core is better described as a bicycle shop :)

2. Saw this typo in the section on input range:

e=r.head Returns the element at the current position, which is of type ElementType!(R). In case ElementType!(R) has aliases (such as a reference, pointer, or array type), the **iterator** is free to recycle it it upon the call to r.next...

3. In output iterator (more bicycle shed stuff):

writing one object and moving to the next one are an organic operation

What's an organic operation?  I'm assuming it means 'coupled' like you can't do one without the other?  I've never heard that term before.

-Steve


September 12, 2008
Bill Baxter <wbaxter@gmail.com> wrote:
> But I do have some suggestions nonetheless!  Marked with ==> below.
> 
> -- Universal --
> r.done
> r.init
> 
> --- Input : Universal ---
> e=r.head
> e=r.next
> r1=r.release  ==> r.transfer?  Release sounds like ref counting (e.g. in COM)
>                           Also seems like r.transfer(r1) could make
> implementation more efficient.
>                           Or perhaps make it a .swap like STL.  Maybe
> you have something against .swap?
> 
> -- Output : Universal --
> r.put(e)
> 
> -- Forward : Input, (optional) Output  --
> r1 = r
> r.head = e
> t=r.after(s)
> 
> -- Bidirectional : Forward --
> e = r.toe
> r.toe = e
> r.reduce           ==> r.retreat  -- aka "pull back"
> t = r.before(s)
> 
> -- Random access : Bidirectional --
> l = r.length
> e = r[n]
> r[n] = e
> r1 = r[n1..n2]
> ------------
> 
> Just those two!

I've got a bit of insight!  XD

-- Common
r.empty

-- InOut
v = r.next;	=> T R.next();
r.next = v;	=> T R.next(T v);

-- Forward: InOut, copyable
v = r.tip
r.tip = v
r1 = r.before(s)
r1 = r.after(s)

-- Bidir: Forward
v = r.prev
r.prev = v
v = r.toe
r.toe = v

-- Random: Bidir
no changes

prev() seems very misleading, otherwise I like it.
September 12, 2008
Andrei Alexandrescu Wrote:

> In wake of the many excellent comments and suggestions made here, I made one more pass through the draft proposal for ranges.
> 
> http://ssli.ee.washington.edu/~aalexand/d/tmp/std_range.html
> 
> There are some comments in red illustrating some uncertainties (not all), and the names of the primitives have been updated. Bicycle shed galore! But don't forget to comment on the reactor as well :o).

The colorful diagram is nice, but it doesn't belong at the top of the article.  Is it possible to find a better spot?  It may be best following the "Coding with ranges also has disadvatages" paragraph.

PS: You're missing an n in disadvantages.  I read past it several times, but my spell checker caught it.
September 12, 2008
Pablo Ripolles wrote:
> What about "isDone"?

isDone is great, I just wanted to keep the one-word streak going. Let's see what everyone else says.

Andrei
September 12, 2008
On Fri, Sep 12, 2008 at 11:22 PM, Sergey Gromov <snake.scaly@gmail.com> wrote:
> Bill Baxter <wbaxter@gmail.com> wrote:
>> But I do have some suggestions nonetheless!  Marked with ==> below.
>>
>> -- Universal --
>> r.done
>> r.init
>>
>> --- Input : Universal ---
>> e=r.head
>> e=r.next
>> r1=r.release  ==> r.transfer?  Release sounds like ref counting (e.g. in COM)
>>                           Also seems like r.transfer(r1) could make
>> implementation more efficient.
>>                           Or perhaps make it a .swap like STL.  Maybe
>> you have something against .swap?
>>
>> -- Output : Universal --
>> r.put(e)
>>
>> -- Forward : Input, (optional) Output  --
>> r1 = r
>> r.head = e
>> t=r.after(s)
>>
>> -- Bidirectional : Forward --
>> e = r.toe
>> r.toe = e
>> r.reduce           ==> r.retreat  -- aka "pull back"
>> t = r.before(s)
>>
>> -- Random access : Bidirectional --
>> l = r.length
>> e = r[n]
>> r[n] = e
>> r1 = r[n1..n2]
>> ------------
>>
>> Just those two!
>
> I've got a bit of insight!  XD
>
> -- Common
> r.empty
>
> -- InOut
> v = r.next;     => T R.next();
> r.next = v;     => T R.next(T v);
>
> -- Forward: InOut, copyable
> v = r.tip
> r.tip = v
> r1 = r.before(s)
> r1 = r.after(s)
>
> -- Bidir: Forward
> v = r.prev
> r.prev = v
> v = r.toe
> r.toe = v
>
> -- Random: Bidir
> no changes
>
> prev() seems very misleading, otherwise I like it.
>

So basically you changed
done ==> empty
head ==> tip
retreat ==> prev
?

I'm actually ok with either "done" or "empty".  "Done" is weird on a random access range, but "empty" is weird on file input range, or a generator.  Or on the HMM example which is "done" when it reaches an end state, but is not really "empty".

"head to toe" is a perfectly common expression, at least in American English.  Not sure why you don't like it.  But tip to toe is kinda cool for being 1 less letter!  And no less clear.

"prev" is horrible.  I still like "retreat" best so far.  We need the contrapositive of "next" not the "opposite".  :-)  And since that doesn't exist we should just go for a word that sorta means the right thing and won't be  confused with being the opposite (or with being something else entirely like "reduce").

--bb