September 09, 2008
On 2008-09-08 17:50:54 -0400, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> said:

> feedback would be highly appreciated. See:
> 
> http://ssli.ee.washington.edu/~aalexand/d/tmp/std_range.html

That looks great. I want to suggest renaming a few functions to make them more consistant and (hopefully) more expressive, as I see I'm not the only one frowning on them.

So right now you're defining this:

r.getNext
r.putNext

r.left
r.next
rightUnion(r, s)
rightDiff(r, s)

r.right
r.pop
leftUnion(r, s)
leftDiff(r, s)

Here's my alternate naming proposal:

r.headNext
r.putNext

r.head
r.next
r.nextUntil(s)
r.nextAfter(s)

r.rear
r.pull
r.pullUntil(s)
r.pullAfter(s)

Note that r.headNext is literally r.head followed by r.next when you have a forward iterator.  You could also add "rearPull" to bidirectional ranges if you wanted. :-)

The syntax is a little different for binary functions (union, diff) as I changed them to members to make things easier to read and more in line with the regular next and pull.

-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/

September 09, 2008
Andrei Alexandrescu wrote:

>> 1)
> There are numerous collections and ranges to be defined

You are right. A reversable range can be built with the designed primitives. But this also holds for the `Retro'-type.

>> 2)
> I used these:
> leftToLeft

Much better, but did you notice, that you used the directionless words "beginning" and "end" to describe their semantics? That's why I used "B" and "E". With directions in the names one might be forced to make wrappers for not being irritated by the directions in case they do not fit.

Ex.: Imagine a 4d-matrix in which a 3d-range is defined diagonally to three of the axis of the 4d-matrix. What is left respective right of such a range?

3) casting

On second read I miss some words about explicite and implicite casting possibilities between the five types of ranges.

-manfred


-- 
If life is going to exist in this Universe, then the one thing it cannot afford to have is a sense of proportion. (Douglas Adams)

September 09, 2008
Michel Fortin wrote:
> On 2008-09-08 17:50:54 -0400, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> said:
> 
>> feedback would be highly appreciated. See:
>>
>> http://ssli.ee.washington.edu/~aalexand/d/tmp/std_range.html
> 
> That looks great. I want to suggest renaming a few functions to make them more consistant and (hopefully) more expressive, as I see I'm not the only one frowning on them.
> 
> So right now you're defining this:
> 
> r.getNext
> r.putNext
> 
> r.left
> r.next
> rightUnion(r, s)
> rightDiff(r, s)
> 
> r.right
> r.pop
> leftUnion(r, s)
> leftDiff(r, s)
> 
> Here's my alternate naming proposal:
> 
> r.headNext
> r.putNext
> 
> r.head
> r.next
> r.nextUntil(s)
> r.nextAfter(s)
> 
> r.rear
> r.pull
> r.pullUntil(s)
> r.pullAfter(s)
> 
> Note that r.headNext is literally r.head followed by r.next when you have a forward iterator.  You could also add "rearPull" to bidirectional ranges if you wanted. :-)
> 
> The syntax is a little different for binary functions (union, diff) as I changed them to members to make things easier to read and more in line with the regular next and pull.

I like the alternate names quite some. One thing, however, is that head and rear are not near-antonyms (which ideally they should be). Maybe front and rear would be an improvement. (STL uses front and back). Also, I may be dirty-minded, but somehow headNext just sounds... bad :o).

I like the intersection functions as members because they clarify the relationship between the two ranges, which is asymmetric. I will definitely heed this suggestion. "Until" suggests iteration, however, which it shouldn't be (should be constant time) so maybe "nextTo" or something could be more suggestive.

This is going somewhere!


Andrei
September 09, 2008
Manfred_Nowak wrote:
> Andrei Alexandrescu wrote:
> 
>>> 1)
>> There are numerous collections and ranges to be defined
> 
> You are right. A reversable range can be built with the designed primitives. But this also holds for the `Retro'-type.

Indeed Retro was provided as a mere example and has no special status. I plan to add some more widely useful ranges, such as a circular range. Contributions will be appreciated (of course after the design gets frozen).

>>> 2)
>> I used these:
>> leftToLeft
> 
> Much better, but did you notice, that you used the directionless words "beginning" and "end" to describe their semantics? That's why I used "B" and "E". With directions in the names one might be forced to make wrappers for not being irritated by the directions in case they do not fit.
> 
> Ex.: Imagine a 4d-matrix in which a 3d-range is defined diagonally to three of the axis of the 4d-matrix. What is left respective right of such a range?  

Good point!

> 3) casting
> 
> On second read I miss some words about explicite and implicite casting possibilities between the five types of ranges. 

Yes, I also mentioned that in a different post.


Andrei

September 09, 2008
Robert Jacques wrote:
> On Mon, 08 Sep 2008 20:37:41 -0400, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
>> Denis Koroskin wrote:
>>> 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.
> 
> I'd warn that changing away from ptr+length would create logical incosistencies between 1D arrays and 2D/3D/ND arrays.

How so?

>>> 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];
> 
> I'd also add that multiple dimension slicing should be supported. i.e.
> auto x = matrix[2..5,0..$,3]
> would become
> auto x = matrix.opSlice(Slice!(size_t)(2,5),Slice!(size_t)(0,matrix.opDollar(0)),3)
> with
> struct Slice (T) { T start; T end; }
> Strided slices would also be nice. i.e. matrix[0..$:10] // decimate the array

Multidimensional slicing can be implemented with staggered indexing:

matrix[2..5][0..$][3]

means: first, take a slice 2..5 that returns a matrix range one dimension smaller. Then, for that type take a slice from 0 to $. And so on.

This works great for row-wise storage. I'm not sure how efficient it would be for other storage schemes.

Note how nice the distinction between the container and its views works: there is only one matrix. But there are many ranges and subranges within it, bearing various relationships with one another.


Andrei
September 09, 2008
Andrei Alexandrescu wrote:

> maybe "nextTo" or something could be more suggestive.

r.tillBeg(s), r.tillEnd(s),
r.fromBeg(s), r.fromEnd(s) ?

-manfred
-- 
If life is going to exist in this Universe, then the one thing it cannot afford to have is a sense of proportion. (Douglas Adams)

September 09, 2008
Jarrett Billingsley wrote:
> On Mon, Sep 8, 2008 at 8:24 PM, Andrei Alexandrescu
> <SeeWebsiteForEmail@erdani.org> wrote:
>> Sergey Gromov wrote:
>>> Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
>>>> Walter, Bartosz and myself have been hard at work trying to find the
>>>> right abstraction for iteration. That abstraction would replace the infamous
>>>> opApply and would allow for external iteration, thus paving the way to
>>>> implementing real generic algorithms.
>>> opApply() wasn't my hero either. :)  Your article really looks like
>>> something I'd expect to find in D.  It only requires foreach support, and
>>> yeah, return by reference.
>> Indeed. Both are in the works.
> 
> Quick question about this one -- how will iterators get foreach
> support?  Are they classes or structs?  If they're structs, how will
> the compiler know something is an iterator?  Or will it be based on
> duck typing (if it looks like an iterator, it must be an iterator)?
> 
> And if this support involves "blessing" certain types within the
> runtime, what will this mean for other runtime libraries?

Great question. We'll go with structs and duck typing (why the heck don't they call it structural typing...) but we'll add interfaces for the range types so that they can be used dynamically too. Code generation will take care of gluing implementations into classes (more on that later).

As someone said in some thread on digitalmars.d, if you start with structs it's easy to move towards classes. The other way around is not as easy.


Andrei
September 09, 2008
Manfred_Nowak wrote:
> Andrei Alexandrescu wrote:
> 
>> maybe "nextTo" or something could be more suggestive.
> 
> r.tillBeg(s), r.tillEnd(s),
> r.fromBeg(s), r.fromEnd(s) ?

Sounds good! Walter doesn't like abbreviations, so probably *Begin would please him more.

Andrei

September 09, 2008
> Great question. We'll go with structs and duck typing (why the heck don't they call it structural typing...) but we'll add interfaces for the range types so that they can be used dynamically too. Code generation will take care of gluing implementations into classes (more on that later).

> Andrei

Probably rhetorical, but I can't help myself:  If it walks like a duck and it talks like a duck, it must be a duck.
September 09, 2008
On Tue, Sep 9, 2008 at 1:06 PM, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
> Manfred_Nowak wrote:
>>
>> Andrei Alexandrescu wrote:
>>
>>> maybe "nextTo" or something could be more suggestive.
>>
>> r.tillBeg(s), r.tillEnd(s),
>> r.fromBeg(s), r.fromEnd(s) ?
>
> Sounds good! Walter doesn't like abbreviations, so probably *Begin would please him more.

But till and until are synonyms.  They both sound like iteration. Although it might be unavoidable since all prepositions that give a destination seem to imply going to that destination.  till, until, toward, to, up to, etc.  So might as well go with the shortest one, "to".

r.toBegin(s), r.toEnd(s)
r.fromBegin(s), r.fromEnd(s)

--bb