Object Curry
Because the proxy is an object, you can use it in a similar way to a curried function in a functional language. In many functional languages, functions only take one argument. They then either return a value or another function. A simple example of this principle occurs in addition. Think of an add function, which takes two arguments and returns the sum. You might write this:
add 12 42
You can also think of this example as two function invocations. The first, add 12, returns a function that adds 12 to its argument. The second invokes this function with 42 as the argument. Nothing stops you from just returning add 12 from a function and then using it elsewhere.
You can do exactly the same thing with higher-order messaging proxies. For example, you can keep the return value from a -map message and send it different messages — not very useful with -map, but consider a -filter message instead. This would have almost the same implementation, but with the following in the loop body:
[anInvocation invokeWithTarget: object]; BOOL shouldAdd; [anInvocation getReturnValue: &shouldAdd]; if (shouldAdd) [filtered addObject: mapped];
If you wanted to extract two different filtered subsets from a collection, you could reuse the same proxy, like this:
id filter = [recipeArray filter]; NSArray *garlicRecipes = [filter containsIngredient: garlic]; NSArray *vegetarianRecipies = [filter isVegetarian];
This way of using higher-order messaging is slightly less natural, but it provides some other options, too. For instance, you could pass a map proxy for an array containing an object that logged every message it received, and another object as an argument to a method. Every message sent to this proxy would be both logged and sent to the original method.
You can add these toNSSet as well as NSArray, using almost the same proxy. You could relatively easily generalize the proxy code to work with different collections, by sending the constructor message to [collection class] instead of NSArray.