Overloading C Functions with Clang
Clang, LLVM's compiler front-end for C-based languages, features a couple of interesting language extensions to C, C++ and Objective-C. You are probably familiar with auto-synthesis of properties or the new subscripting syntax.
One of the lesser known extensions, however, is the __attribute__((overloadable))
annotation.
While languages like Java and C++ allow you to define multiple functions with the same name but different arguments, this feature has been absent from C.
However, using recent versions of Clang you can now rectify this behavior and since Objective-C is a superset of C, knowing how to use this feature can be useful even if you rarely venture outside of Cocoa or Cocoa Touch.
Consider for example these function declarations:
We declare two different versions of the classic map
function.
Instances of NSArray will have a block applied to their elements that takes a
single argument while instances of NSDictionary have both their keys and values
sent to the block.
The compiler will figure out which map
it needs to call simply based on the
types of the arguments.
The implementation is pretty straightforward, too:
-[NSArray enumerateObjectsUsingBlock:]
is used to iterate over all elements.
If the block passed to map
returns nil
, the element is discarded.
You may want to consider writing a parallel version of map
that makes use of
-[NSArray enumerateObjectsWithOptions:usingBlock:]
and passes in
NSEnumerationConcurrent
.
The implementation for dictionaries looks similar:
Now we have a nice and clean way to map over Cocoa's most prevalent data structures:
I think function overloading is a welcome addition to C and it goes to show how knowing the underpinnings of Objective-C can help you write better and more concise code.
Update: Nick Lockwood raised the point that map
may be
better suited for a category. When I came up with this example, I was also
considering an each
implementation that could deal with
id<NSFastEnumeration>
. E.g.:
That being said, if you're looking for a solid and well tested map category, check out BlocksKit.
Posted in thinking-about