In the previous article, I made the following observation: A collection that holds its elements but doesn't allow you to traverse them is unlikely to prove popular. There are many ways to offer traversal, but if the caller needs to be able to know the position of elements in some way there are essentially only three general …
Enumeration method doesn't have to be painful
If provided by the framework. NeXT's Foundation classes had this years ago and it followed through into Java implementations after Apple bought it, for example at http://developer.apple.com/documentation/WebObjects/Reference/API/com/webobjects/foundation/NSArray.html#objectEnumerator() - nice, and easy to work with.
Er, in good ol' C....
Pardon me being dumb, but is it not reasonable, in the absence of closures, to just go:
DoIterate(void (*func)(dataType data, void * context),void * context);
So the iteration request consists of both a processor function and a void* (which you cast to your object*).
Just a quick clarification: a java.util.Enumeration, as shown in the NeXT example, is an example of the Iterator pattern not the Enumeration Method pattern. Yes, the name is confusing.
One of the defining characteristics of Enumeration Method is that the user of a collection does not write the loop: the collection encapsulates the loop mechanism. The Enumeration Method itself calls back to code provided by the caller.
In terms of callbacks, yes, in C it is possible to do this, as the article pointed out -- "it is not a pattern that is restricted to Smalltalk: it can be applied in C, using function pointers". However, the downside is that without closures, generics, an object-based type system or other suitable mechanisms you can end up with void * all over the place.
In response to the comments on the NeXT NSEnumerator class, that in itself is not the Enumeration approach but it's certainly simple to achieve in Objective-C; the technique seems to have received the sobriquet "Higher-Order Messaging". Certainly searching cocoadev.com for HOM yields a few examples of the style.
Three or four... but which ones?
Thanks, Kevlin, for publishing a second article on why my response to "Up with cohesion, down with coupling" was wrong!
(Readers, you can see the first response article here: http://www.regdeveloper.co.uk/2006/09/04/to_iterate_human/)
The Iterator does not give the caller any valuable information on the position of elements, so the constraint "if the caller needs to be able to know the position of elements in some way" does not in fact differentiate between internal and external iterators. In fact, the word "position" implies order, and external iterators apply just as well to unordered collections like your sets and your hash-maps. (Of course, because iterating over elements is what most collections are for.) Yes, an Iterator does encapsulate position, but preferably doesn't expose that implementation-specific detail, for compatibility with different kinds of collection.
Again, you downplay Lisp's fold functions for providing more than just the element to the loop function, but these functions demonstrate how "position of the elements" and other context as required by task constraints can naturally be included in your external iterator. Thus your constraint allows internal iterators while excluding Java's preferred Iterators.
Furthermore, I put it to you again that while iteration over a collection is a very common idiom, this constraint is very rarely necessary. That's why using for-each makes sense in any language that provides such syntax.
I think I adequately explained the benefits of external iterators in my response to your first article -- chiefly, they encapsulate the most common function of a collection class within the class, and don't expose those implentation-specific details to the users of the class.
Hayden Clark, as dumb as he claims to be, has shown how simple it is to bring the pattern to C. You don't need "closures, generics, an object-based type system or other suitable mechanisms." And (void *)'s are cool, anyway. All it says is "I don't feel then need to nail down a type here."
- Updated Microsoft Azure goes TITSUP (Total Inability To Support Usual Performance)
- Review Apple takes blade to 13-inch MacBook Pro with Retina display
- Munich considers dumping Linux for ... GULP ... Windows!
- Game Theory The agony and ecstasy of SteamOS: WHERE ARE MY GAMES?
- Pic iPhone 6 flip tip slips in Aussie's clip: Apple's 'reversible USB' leaks