Pebble's Diary

プログラマーの作業メモ

JavaScript 関数を引数に取る関数

関数を引数に取る関数の複雑なケースです。

function process(f) {
    f( function(name, g) {
        print( name );
        g( 100 );
    });
}
process(
    function(h) {
        h( "hoge", function(value){
            print( 2 * value ); 
        });
        h( "fuga", function(value){
            print( 3 * value );
        });
    }
);
// hoge
// 200
// fuga
// 300

JavaScript初心者にはなかなか難しいですが、これを型言語であるObjective-CのBlocksを使って書き直すとこうなります。

#import <Foundation/Foundation.h>

typedef void (^G)(int value);
typedef void (^H)(NSString* name, G g);
typedef void (^F)(H h);

void process(F f) {
    f( ^(NSString* name, G g){
        NSLog( @"%@", name );
        g( 100 );
    });
}
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        process( ^(H h){
            h( @"hoge", ^(int value){
                NSLog( @"%d", 2 * value );
            });
            h( @"fuga", ^(int value){
                NSLog( @"%d", 3 * value );
            });
        });
    }
    return 0;
}
// hoge
// 200
// fuga
// 300

JavaScriptの方が型定義が不要な分、少ないソース量で複雑なことをやっていることが分かります。