Believe it or not, sometimes it actually rains in Southern California. Which in turn means that I have to drive home from work in the rain. No big deal, unless you're already on the road when it starts to rain. Then all the dirt and oil and grime that has built up in the last months since the last great purging turns into a nice sheen as slippery as ice.
mathcad ttdownAfter that, you're in the clear ... if you have a boat. The roads in Southern California don't drain. The water just collects in the middle of the road so that we can practice our hydroplaning. BMW's Alaskan ice driving school gots nothing on us, yo. The drainage on the surface streets is virtually nonexistent, which led me to comment (on my cell phone while I was driving, naturally) that there is no excuse for improper engineering.
I have to write code for Windows every day, with its ugly API's and inconsistent interfaces. Do I use that as an excuse to write shoddy code? No. I expect the same quality of engineering for everything I consume, especially when I have no choice in the matter. I mean, I can picture some manager saying, "It only rains 3 days a year, so our roads don't need to have that feature."
Recently I've been discovering a lot of developer related journals. You might say I've been iterating over them. I've been thinking a lot about language design and code design, especially focusing on generic programming. I came across this article on Cocoa's NSEnumerator, which is a topic I've been toying with in various contexts. Traversing an XML tree; walking a list of channels; processing a dictionary of commands. All of these require some form of iteration. The aforementioned article references different types of iteration idioms which I won't repeat here, but I did want to point out a different solution to Mr. Rentzsch's proposal.
NSArrays are toll-free bridged to CFArrayRefs which means that you could do the following:
typedef __SomeStruct IteratorContext;
void processObjectFromArray( CFArrayRef array, void* object, void* context )
{
NSLog( (id)object );
}
- (void) processList: (NSArray*) list
{
IteratorContext ctx = {NULL};
CFArrayApplyFunction( (CFArrayRef)list, &processObjectFromArray, &ctx );
}
Of course, this is trading ugly preprocessor macros for ugly C with void pointers when what we really want to write is nice pretty Objective-C. Surely we can do that:
@interface NSArray (InkExtensions) - (void) iterateWithObject: (id) object andSelector: (SEL) method; @end