On 13/07/10 17:23, Didier 'Ptitjes' wrote: > All in all, breaking the ABI/API is not a problem, as we still have at > least one anticipated round of developement where we do expect to break > the ABI. So don't let that limit your imagination/creativity/engineering... I've done some thinking and I'm somehow unhappy about current Iterator<G> design (I was discussing it before but it wasn't so big problem as it was on iterator-as-primary-thing-we-operate-on). I know that would be a big change in interface so it may be something we should be really careful. The problem is that we have 2 somehow separated states: - Before start or after delete when we point between elements +---+---+---+---+ +---+---+---+---+ | | | | | | | | | | +---+---+---+---+ +---+---+---+---+ ^ ^ | | - After start when we point at elements +---+---+---+---+ | | | | | +---+---+---+---+ ^ | Problems: 1. If we want to skip lets say odd elements from the beginning we have to create a new GObject (which is not exactly lightweight). Instead if we had a list: +---+---+---+---+ | 1 | 3 | 2 | 4 | +---+---+---+---+ We check if next element exists. Then we move onto it and checks if it is odd. 1, 3 aren't - 2 and 4 are. So now we point at 2: +---+---+---+---+ | 1 | 3 | 2 | 4 | +---+---+---+---+ ^ | However if we would treat it as start of iterator we would get: next() --> true get() --> 4 (!!!) next() --> false skipWhile would not behave as iterator at all. (similar 'problem' I had with ReverseIterator) Solution: a) Add is_pointing or similar property and check if the iterator is pointing somewhere then perform is_next (breaks API/ABI and produces horrible code) b) Point always on element, past-the-end or before-the-beginning like in C++/STL. c) Just return a new iterator in skip operations. d) Add get_next/lookahead methods 2. The remove method makes no sense for the many of iterators now. For example: Iterator<int> iter = new ArrayList(...).map(String.to_int); if(iter.next()) { iter.remove(); // ??? } Yes - we can use assert_not_reached but... well what's the point of method in interface for which 99% of implementation would have it. (On second thought - many operations resulting in iterator would have some corresponding element. Event to the extend of: ...() .map (String.to_int).remove_if ((x) => return x % 2 == 0) // The same as ...() . remove_if ((x) => return x.to_int % 2 == 0)) 3. first/last methods requires caching. I admit - they were my ideas but I guess they were bad - or rather should be reversed. If the Iterator<G> have first method it have to save all elements before if iteration have side-effects. And in impure FP style it can: iter.map((file) => { stderr.printf("Read" + file); return open(file).read_all() }); As the point of doing interators is to do it on-the-fly I would suggest moving first to BidirIterator<G> as it can be implemented in terms of prev anyway. 4. Rather suggestion for vala: foreach should work for iterators. Reggards
Attachment:
signature.asc
Description: OpenPGP digital signature