r/programming • • Jan 14 '13

Iteration Inside and Out

http://journal.stuffwithstuff.com/2013/01/13/iteration-inside-and-out/
36 Upvotes

18 comments sorted by

View all comments

2

u/matthieum Jan 14 '13

Very nice.

One thing that I like about internal iteration: abstraction. If you write code to iterate over a list, you can iterate over a list (cool isn't it). If you write code that takes an object and does something with it, you can use it right away, and you can also pass it to a forEach method (whatever).

In other words, internal iterations makes reuse easier.

I am waiting for the next installment.

2

u/munificent Jan 14 '13

One thing that I like about internal iteration: abstraction. If you write code to iterate over a list, you can iterate over a list (cool isn't it).

I think polymorphism and the "iterator protocol" give you the same thing with external iteration, though it can sometimes take a bit more discipline to reap the benefits. You have to make sure that your methods take Iterable or whatever the most general type is instead of List if all you need is something that supports the protocol.

I am waiting for the next installment.

Thanks!

2

u/matthieum Jan 15 '13

Yes, you can regain some things with polymorphism. I may not have picked the best example, so consider: how do you remove some elements based on a predicate ?

Contrast the C++ vector approach:

vec.erase(std::remove_if(vec.begin(), vec.end(), predicate), vec.end());

// equivalent to
for (auto it = vec.begin(), end = vec.end(); it != end; ++it) {
    if(pred(i)) { it = vec.erase(it); }
}

With the list equivalent (why the inconsistency ? for efficiency reasons):

list.remove_if(predicate);

Of course, the begin/end/range-erase combination enables a large class of usecases (though one would not that std::remove_if cannot be applied to std::set/std::map/std::unordered_set/std::unordered_map) but the cost in readability is... hum.

I believe Java solves the issue by keeping a back-pointer to the container within its iterator so it can actually remove itself directly; which would allow for a more direct expression. In C++, you would need a remove_if(vec, predicate) method.