Bidirectional iterators, seeking advices

question#1: any ideas if it makes sense not having a sentinel element?

I’d say no. Feel free to have one internally, but you don’t have to show it
to the user of your iterator API. Encapsulate it in your Iterator#next
method. In STL it is exposed to make ordinary pointers work as iterators, as
used in std::vector<> and ordinary contigious blocks of memory. It could
have been abstracted away in C++ too, but for STL performance is king!

question#3: which implementation of iterators do you think is ideal?
where do I have to look? java, stl, python?

Why? The history and nature of the implementation language/platform is
important. For instance in STL there are some hoops that the implementation
jumps through to make ordinary pointers (to a contiguous block of memory)
iterators. Including the use of trait classes (because you cannot assign
traits directly to a pointer class, there is no such class) and the use of
operator overloading, and the way the end is checked, ie. it !=
container.end(). These design considerations are invalid for ruby. The STL
iterator concept is finer grained with ForwardIterators,
BlahBlahIterators… Iterators in .net and Java are extremely simple, and
follows the basic GoF pattern pretty much to the letter, without anything
fancy.

Have you noticed that ruby’s iterator concept (using each) is less general
than the concepts in java, STL, .net? In rubydotnet I can easily detect when
an object passed to ruby from .net is IEnumerable and implement ‘each’ on
the proxy in terms of the IEnumerable interface and mixin Enumerable, but
the reverse is not true, because the iteration state in ruby is “on the
stack”, it is not encapsulated in an object. The same problem is causing
some headaches if you want to iterate in parallel over 2 or more
Enumerables. Less flexible, but more elegant.

What prompted you to look into this?

Cheers,

Tom