Friday, October 09, 2009

(Simplified) Block/Closure Extension to C/Objective C/C++


My previous post from yesterday showed the new block/closure feature of the C language. I think I may have made the block syntax more complex looking than it needed to be by including the full interface/object code along with it. So today I'll strip off some of that unneeded code and do a comparison of just the basic syntax of C/ObjC's new block with that of C#'s anonymous method.



(block 1)
- ObjC
typedef void(^Block)(char*);

- C#
delegate void Block(string msg);

(block 2)
- ObjC
- (void) test: (Block)block {
    block("msg");
}

- C#
protected void Test(Block block) {
    block("msg");
}

(block 3)
- ObjC
int main( int argc, const char *argc[] ) {
    MyClass *mc = [[MyClass alloc] init];

    [mc test: ^(char *msg) { printf("%s"), msg } ];
}

- C#
static void main( string[] args ) {
    MyClass mc = new MyClass();

    mc.Test((string msg) => { Console.WriteLine(msg); } );
}

Blocks 1 and 2 only have minor differences between the languages.
Block 3 has the most difference between the languages due to the SmallTalk like message passing syntax of ObjC
    [obj msg] vs that of c#'s obj.msg
Like blocks 1 and 2, block 3 shows only minor differences between the block syntax in either language.

^() { }
vs
() => { }

3 comments:

BlackTigerX said...

that's a good try, except #3, in C# you could've written it like this:

mc.Test(msg => Console.WriteLine(msg));

Justin Wilson said...

It's all syntactic sugar :)

mc.Test(msg => { Console.WriteLine(msg); });
mc.Test((string msg) => { Console.WriteLine(msg); });
mc.Test(delegate(string msg) { Console.WriteLine(msg); });
mc.Test(new Block(delegate(string msg) { Console.WriteLine(msg); }));

Justin Wilson said...

That could also be considered more of a type-inference feature than an anonymous method feature.

Removing the type-inference would leave you with code similar to the code in block 3.