How to write lambda methods in Objective-C?

Objective CFunctional ProgrammingLambda

Objective C Problem Overview


How to write lambda methods in Objective-C ?

Objective C Solutions


Solution 1 - Objective C

The concept of a lambda in Objective-C is now encapsulated with the idea of [Blocks][1] which are the equivalent of pass-by-reference functions. Of course, arguably one had that already in C with the idea of function pointers; blocks are just a way of also capturing local state (i.e. can be closures). In fact, blocks can also be used in other C languages as well (on Mac) - there's a proposal to make them part of the standard C syntax.

Here's an example of defining a lambda to multiply two numbers together:

int (^mult)(int, int) = ^(int a, int b) { return a*b; };

The first part declares a variable, of type ^int(int,int) and then assigns it to the lambda expression (aka block) which returns the multiple of its two arguments. You can then pass that fn around, define it in other places etc; you can even use it in other functions.

Here's an example of defining a function, which when invoked, returns another function:

multiplyBy = ^(int a) { return ^(int b) { return b*a; }; };
triple = multiplyBy(3);

Note that you can intermix blocks with object types (usually using id as the object type) and many of the new Objective-C object data structures have some kind of block-level operation. GCD also uses blocks in order to pass in arbitrary events; however, note that GCD can also be used with function pointers as well.

[1]: http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/Blocks/index.html "Blocks"

Solution 2 - Objective C

OS X 10.6 introduced blocks. See AlBlue's answer for examples.

If you're not using Snow Leopard, you can get something close to function composition using various other features.

Example using C function pointers:

void sayHello() {
    NSLog(@"Hello!");
}

void doSomethingTwice(void (*something)(void)) {
    something();
    something();
}

int main(void) {
    doSomethingTwice(sayHello);
    return 0;
}

Example using the command pattern:

@protocol Command <NSObject>
- (void) doSomething;
@end

@interface SayHello : NSObject <Command> {
}
@end

@implementation SayHello
- (void) doSomething {
    NSLog(@"Hello!");    
}
@end

void doSomethingTwice(id<Command> command) {
    [command doSomething];
    [command doSomething];
}

int main(void) {
    SayHello* sayHello = [[SayHello alloc] init];
    doSomethingTwice(sayHello);
    [sayHello release];
    return 0;
}

Example using a selector:

@interface SaySomething : NSObject {
}
- (void) sayHello;
@end

@implementation SaySomething
- (void) sayHello {
    NSLog(@"Hello!");    
}
@end

void doSomethingTwice(id<NSObject> obj, SEL selector) {
    [obj performSelector:selector];
    [obj performSelector:selector];
}

int main(void) {
    SaySomething* saySomething = [[SaySomething alloc] init];
    doSomethingTwice(saySomething, @selector(sayHello));
    [saySomething release];
    return 0;
}

Solution 3 - Objective C

I heard André Pang at NSConference talking about how blocks were going to be introduced with the next version of Objective-C.

This should allow functional programming.

Edit: Since Snow Leopard has been released, this is indeed the case. Objective-C now has Blocks.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionWho knowsView Question on Stackoverflow
Solution 1 - Objective CAlBlueView Answer on Stackoverflow
Solution 2 - Objective CWill HarrisView Answer on Stackoverflow
Solution 3 - Objective CAbizernView Answer on Stackoverflow