September 12, 2008
On Fri, Sep 12, 2008 at 11:58 PM, Sergey Gromov <snake.scaly@gmail.com> wrote:
>>
>> So basically you changed
>> done ==> empty
>> head ==> tip
>> retreat ==> prev
>> ?
>
> The insight was about get/put ==> next.  That's the most significant change, others are merely renames as you rightfully point out.  Hence the "prev" which should mean both "get at the end" and "put to the end".

Ah ok.  Your switching to declaration syntax instead of usage syntax confused me. :-)

That is cute.  So
   r.put(e) ==> r.next = e
It would also mean the copy to output idiom would become

for(; ! i.done; i.next)
   o.next = i.head;

Would be cooler if it could be just while(!i.done) o.next = i.next;
.. oh well.

But maybe it's too cute for too little gain?  It's pretty darn obvious what a "put" function is for.  you can also search for it more easily then a bunch of next's that could be either writes or not writes.

--bb
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 found superdan's post that convinced you.  I honestly cannot see why.

Suppose I want to allow recycling in empty/next pair.  Then I cpecify
that:
* next() returns stuff;
* stuff is guaranteed to survive until the subsequent call to next();
* stuff becomes undefined after next() is called again;
* stuff is guaranteed to survive intermediate calls to empty().

The last point can make implementation more complex in some cases but it's definitely possible to implement.

If we revert to empty/next, or whateve names you think better, then we can also revert to using first/last for forward/bidirectional range outermost elements and stop that body parts discussion.

I really hope this makes sense.
September 12, 2008
On Sat, Sep 13, 2008 at 12:29 AM, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
> Bill Baxter wrote:
>> 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?
>
> Are you kidding? I wrote the best swap in the world. Check the source of std.algorithm.

I mean like stdvector.swap(stdvector0), not the algorithm swap.  Or maybe your swap subsumes both kinds?

> You'll have to convince Bartosz about dropping the name "release". He held a gun to my head, and five of the six chambers were loaded. Couldn't take the risk.


Hmm.  I would have thought Walter would veto "release" since he cared enough about COM to write it into the D spec.   Release is *the* word used throughout COM to signal that you want to decrement an objects reference counter.  So basically you do an obj->Release on a COM object any time you would have done a "delete obj" on a regular object.

> As far as efficiency goes, Walter has RVO down and all so I'm not worried.

What if you don't put a return object there?  Will that be ok too? Even if there are OS resources and such involved?

--bb
September 12, 2008
Bill Baxter Wrote:

> On Sat, Sep 13, 2008 at 12:03 AM, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
> > Bill Baxter wrote:
> >>
> >> On Fri, Sep 12, 2008 at 11:39 PM, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
> >>>
> >>> 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.
> >>
> >> Hmm.  std.algorithm does have an "isSorted" function.  So I guess I agree it would be more consistent if you call it isDone or isEmpty.
> >>
> >> Or rename "isSorted" to "sorted".  :-)  But then you have to face the consequences later when you want to have a predicate that is ambiguous without the "is".    Probably a lot of noun predicates are in that category -- i.e. checking  isSomeNoun(x).  Like "isRange(x)" to see if x is a range.  That would have to just become "range(x)" which is a bit ambiguous.
> >>
> >> So I agree. Stick the "is" in there.
> >
> > Thing is, people will call isSorted much less often than (isD|d)one. In std.algorithm clearly the one-word paradigm can't scale. But for a handful of heavily-used names I'd be willing to take the Pepsi challenge.
> >
> > Andrei
> >
> > P.S. The more I think of it, the more I like "tip" of the range. Short, poignant, easy to remember. Not pressing the red button just yet.
> 
> Hmm.  One semantic issue I have is that the tip usually refers to the infinitessimal point at the end.  Not a thing with substance.  I'm having trouble feeling like I'm going to get an item back when I look at "x.tip".  Head has huge history being used for the item at the front of a list, so I think that's much less likely to cause anyone looking at D code to scratch their heads.  It will be obvious what it means even in relative isolation.  head/tip will often appear without "toe" in forward range algos.  So you need to be able to easily recognize what "tip" means without seeing that "toe" to give context. Toe on the other hand will probably almost always appear with his mate.
> 
> Ooh, another scale thing, but a head is obviously a very different scale than a toe.  A foot is closer to the same scale.  Maybe head/foot is better than head/toe.  The connection between retreating / feet is stronger that retreating / toes, too!
> 
> --bb

neither the tip of the tail, nor the tip of the wing, nor the tip of the flagellum are really infinitesimal...

I'm not sure whether I understand your reasoning about the "tip" / "toe", I interpreted that "tip" could be a substitute of "toe"...

my problem with foot is that there is necessarily more than one.

perhaps in the world of the anatomy of the chordates we can find something... dunno, "coccyx" is pretty weird but at least there is only one.

Cheers!


September 12, 2008
Bill Baxter <wbaxter@gmail.com> wrote:
> On Fri, Sep 12, 2008 at 11:58 PM, Sergey Gromov <snake.scaly@gmail.com> wrote:
> >>
> >> So basically you changed
> >> done ==> empty
> >> head ==> tip
> >> retreat ==> prev
> >> ?
> >
> > The insight was about get/put ==> next.  That's the most significant change, others are merely renames as you rightfully point out.  Hence the "prev" which should mean both "get at the end" and "put to the end".
> 
> Ah ok.  Your switching to declaration syntax instead of usage syntax confused me. :-)
> 
> That is cute.  So
>    r.put(e) ==> r.next = e
> It would also mean the copy to output idiom would become
> 
> for(; ! i.done; i.next)
>    o.next = i.head;
>
> Would be cooler if it could be just while(!i.done) o.next = i.next;
> .. oh well.

Exactly, I wanted it to be

while (!i.done)
    o.next = i.next;

because I didn't want any head in an input range.

> But maybe it's too cute for too little gain?  It's pretty darn obvious what a "put" function is for.  you can also search for it more easily then a bunch of next's that could be either writes or not writes.

I'm still not sure.  The usability can only be measured by actual usage.
September 12, 2008
On Sat, Sep 13, 2008 at 1:03 AM, Pablo Ripolles <in-call@gmx.net> wrote:
>> Hmm.  One semantic issue I have is that the tip usually refers to the infinitessimal point at the end.  Not a thing with substance.  I'm having trouble feeling like I'm going to get an item back when I look at "x.tip".  Head has huge history being used for the item at the front of a list, so I think that's much less likely to cause anyone looking at D code to scratch their heads.  It will be obvious what it means even in relative isolation.  head/tip will often appear without "toe" in forward range algos.  So you need to be able to easily recognize what "tip" means without seeing that "toe" to give context. Toe on the other hand will probably almost always appear with his mate.
>>
>> Ooh, another scale thing, but a head is obviously a very different scale than a toe.  A foot is closer to the same scale.  Maybe head/foot is better than head/toe.  The connection between retreating / feet is stronger that retreating / toes, too!
>>
>> --bb
>
> neither the tip of the tail, nor the tip of the wing, nor the tip of the flagellum are really infinitesimal...
>
> I'm not sure whether I understand your reasoning about the "tip" / "toe", I interpreted that "tip" could be a substitute of "toe"...

Nope.  I'm pretty sure that the discussion is about replacing "head" with "tip".  There's an expression "from tip to toe".

But I think your confusion (or is it mine?) about which end would be
the tip is pretty damning.

> my problem with foot is that there is necessarily more than one.

There's also more than one toe.  But I guess you thought that "toe" was out.

> perhaps in the world of the anatomy of the chordates we can find something... dunno, "coccyx" is pretty weird but at least there is only one.

Well, there is only one tail... but it's what functional guys call everything but the head, so Anrdrei wants to avoid it.

--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).
> 
> 
> Andrei

Two questions:
- Is it possible to add elements to a range? Suppose a linked list, you want to traverse it's elements until a condition is met on an element, and then add something after it. Or before it. I see there's "put", but it also says "An output range models a one-pass forward writing iteration.", so I think it's not the same.
- The same question applies if you want to delete an element from a range.

As for the names, I think it's impossible to find one-word names for the concepts you want to express. I always prefer expressive, easy to remember names instead of shorter but less meaningful names. Maybe:

head --> first
toe --> last
next --> moveFirst / dropFirst / skipFirst
retreat -> moveLast / dropLast / skipLast
done --> isEmpty (it's strange to think of a range as done)

So it's like dropFirst / dropLast shrink the range from either end, until it's empty.

Sorry if these things were already discussed, I didn't have time to read the hundreds of posts of the previous discussion, just some and the next proposal.
September 12, 2008
Ary Borenszweig <ary@esperanto.org.ar> wrote:
> Two questions:
> - Is it possible to add elements to a range? Suppose a linked list, you
> want to traverse it's elements until a condition is met on an element,
> and then add something after it. Or before it. I see there's "put", but
> it also says "An output range models a one-pass forward writing
> iteration.", so I think it's not the same.
> - The same question applies if you want to delete an element from a range.

The idea is that a container is responsible for mutators, not range.
Therefore you'd have list.insertBefore(range, value).  Likewise there'd
be list.remove(range), list.removeBefore(range) and list.removeFirst
(range).
September 12, 2008
Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
> Sergey Gromov wrote:
> > *)
> > 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.
> 
> Neither of next and retreat should return a value. In wake of constructors/destructors, we shouldn't return by-value lightly.

Then, in Input range primitives, e=r.next must be just r.next.
September 12, 2008
Sergey Gromov wrote:
> 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 found superdan's post that convinced you.  I honestly cannot see why.
> 
> Suppose I want to allow recycling in empty/next pair.  Then I cpecify that:
> * next() returns stuff;
> * stuff is guaranteed to survive until the subsequent call to next();
> * stuff becomes undefined after next() is called again;
> * stuff is guaranteed to survive intermediate calls to empty().
> 
> The last point can make implementation more complex in some cases but it's definitely possible to implement.
> 
> If we revert to empty/next, or whateve names you think better, then we can also revert to using first/last for forward/bidirectional range outermost elements and stop that body parts discussion.
> 
> I really hope this makes sense.

He did convince me. With your API you can't write efficient algorithms that work with input ranges and forward ranges crawling on actual containers.

Andrei