RFC on range design for D2
Fawzi Mohamed
fmohamed at mac.com
Wed Sep 10 04:31:57 PDT 2008
On 2008-09-10 01:02:00 +0200, Andrei Alexandrescu
<SeeWebsiteForEmail at erdani.org> said:
> Fawzi Mohamed wrote:
>> are you sure? then a range is *exactly* equivalent to a STL iterator,
>> only that it cannot go out of bounds:
>> // left1-left2:
>> while((!i1.isEmpty) && (!i1.atSamePlace(i2))){
>> i1.next;
>> }
>> // left2-left1:
>> while((!i2.isEmpty) && (!i1.atSamePlace(i2))){
>> i1.next;
>> }
>> // union 1-2
>> while((!i1.isEmpty) && (!(i1.atSamePlace(i2))){
>> i1.next;
>> }
>> while(!i2.isEmpty){
>> i2.next;
>> }
>> // union 2-1
>> ...
>> // lower triangle
>> i1=c.all;
>> while(!i1.isEmpty){
>> i2=c.all;
>> while(!i2.isEmpty && !i2.atSamePlace(i1)){
>> i2.next;
>> }
>> well these are the operations that you can do on basically all
>> iterators (and with wich you can define new iterators).
>> The one you propose need an underlying total order that can be
>> efficiently checked, for example iterators on trees do not have
>> necessarily this property, and then getting your kind of intersection
>> can be difficult (and not faster than the operation using atSamePlace.
>
> I am getting seriously confused by this subthread. So are you saying
> that atSamePlace is your primitive and that you implement the other
> range operations all in linear time? If I did not misunderstand and
> that's your design, then you may want to revise that design right now.
> It will never work. I guarantee it.
It desn't seem to difficult to me, just look at the code, they are
iterations on subranges of iterators i1 and i2, actually they are the
only kind of range combination that can be performed safely on general
iterators.
The range combinations you propose are cumbersome rarely used and in
general unsafe, I think that it is a bad idea add them to the object
that is needed to get some foreach magic, and the most generic iterator.
atSamePlace returns true if two iterators have .left (or however you
call it) at the same place (and in general this might not mean that
they have the same address) can be implemented for almost all iterators
in constant time (at the moment I cannot think of a counter example),
and with it (as the code just above shows) you can define some
subranges.
In the case in which you have a easily checkable total ordering between
the elements then yes you do have all the all that it is needed to have
a real range, and for this range object your subrange operations are
safe, and I am not against them, just don't force them on every person
that wants just to iterate on something.
>> the only new thing is bidirectional iterator: an iterator that can go
>> in both directions as extra iterator type (your bidirectional range is
>> something different).
>
> A bidirectional range is simply a range that you can shrink from either end.
That is exactly what I said it the sentence before, but in this
sentence I am speaking about a bidirectional *iterator* that for me is
an iterator that can move both back and forth.
>> I think it is useful and I don't see the need to shoehorn it into a
>> range. For me an iterator is an object that can generate a sequence by
>> itself, so a range is an example of iterator, but I don't see the need
>> to make each iterator a range.
>
> I have put forth reasons for doing away with iterators entirely in the
> range doc. What are your counter-reasons for bringing back iterators?
they are simpler and describe a larger range of useful constructs
ranges on liked list as I said are unsafe, which does not meant that
ranges are not useful, just that there is a place also for simple
iterators.
Iterators can be perfectly safe it is just the C++ idea of un-bundling
the end from the iterator that makes it unsafe (an also more cumbersome
to use).
If iterator for you for you is too connected with C++ view of it call
them generators: a self containde object that can generate a sequence.
bidirectional iterators are a natural step in the progression of
iterators also they can be implemented safely.
>> As I said before a range also has a total ordering of the objects that
>> can be easily checked, this is a special king of iterator for me, not
>> the most general. Take two ranges of two linked lists, you cannot
>> easily build your intersections because you don't know their relative
>> order, and checking it is inefficient.
>
> Correct. The range intersection primitives are Achille's heel of the
> range-based design. Checking subrange reachability is O(n), so the
> range intersection primitives take the user by faith. But iterators
> have that Achille's heel problem too, plus a few arrows in their back
> :o). The document clarifies this disadvantage by saying that range
> intersection primitives are undefined if certain conditions are not met.
>
> In short, this is an endemic problem of an iteration based on either
> ranges or individual iterators. An objection to that should
> automatically come with a constructive proof, i.e. a better design.
using atSamePlace you can do it safely on any kind of ranges, I think
that the operation available should only be safe, and they can be safe,
in general using atSamePlace, and if there is a quickly checkable total
ordering (as in arrays for example) by never letting a range be larger
than the union of two ranges.
One can then discuss if segment it (and the result would be an iterator
but not a range) or choose only one side (keep it a range) if the two
ranges are disjoint and have a hole between them.
>>>> So this is what "my" iterator/range would look like :)
>>>
>>> I encourage you to realize your design. Before long you'll find
>>> probably even more issues with it than I mentioned above, but you'll be
>>> gained in being better equipped to find proper solutions.
>>
>> I hope we converge toward a good solution ;)
>
> Well I haven't seen much code yet.
I have written quite some code in my multidimensional array library (
http://github.com/fawzi/narray ) and I thought a lot about iterators,
not only in D, but in the several languages that I know.
As with everybody I don't think to really see all implications of the
interface, but I think that I understand them enough to participate
meaningfully to this discussion.
Actually the moment I am really busy, but I am trying to say something
because I think this discussion is important for the future of D, and I
care about it.
I will try to give some real code, but I thought that my contribution
was not so difficult to understand, but it is always like this to
yourself one always seems clear ;)
Fawzi
More information about the Digitalmars-d-announce
mailing list