-
-
Save nsforge/4342663 to your computer and use it in GitHub Desktop.
@interface MyRequest : NSObject | |
// Variation One | |
- (void)startRequestWithCompletionBlock1:(void (^)(MyRequest *request))completionBlock; | |
// Variation Two | |
- (void)startRequestWithCompletionBlock2:(void (^)(id request))completionBlock; | |
// Variation Three | |
- (void)startRequestWithCompletionBlock3:(void (^)(instancetype request))completionBlock; | |
@end | |
... | |
@interface MyRequestSubclass : MyRequest | |
- (void)aSubclassMethod; | |
@end | |
... | |
// Usage | |
MyRequestSubclass *request; | |
[request startRequestWithCompletionBlock1:^(MyRequest *request){ | |
MyRequestSubclass *requestAsSubclass = (MyRequestSubclass *)request; // typecast from MyRequest* to MyRequestSubclass* loses type safety | |
[requestAsSubclass aSubclassMethod]; | |
}]; | |
[request startRequestWithCompletionBlock2:^(MyRequestSubclass *request){ // typecast from id to MyRequestSubclass* loses type safety | |
[request aSubclassMethod]; | |
}]; | |
[request startRequestWithCompletionBlock3:^(instancetype request){ // typesafe | |
[request aSubclassMethod]; | |
}]; |
Thanks for your feedback. When you say that that's "how C works", do you mean that that's how C compilers (including Clang) are currently implemented, or that this bottom up expression parsing and type checking is fundamental to the language itself? Would this sort of thing be implementable in Obj-C++ (just playing devil's advocate)?
The bottom up expression parsing and type checking is fundamental to the language itself. There are some cases where we can add limited type inference because it happens to work within the limitations of the language, e.g. instancetype or auto in C++11, but those are very limited cases. If you look at a language where type inference is a fundamental component, e.g. OCaml, the language parsing rules and type system are very different. In such a language, the type information can flow both up and down an expression tree, while in C this isn't possible.
Got it. That's not what instancetype was really invented for. It was used to describe the type signatures of methods, not auto-deduce arguments. There's nothing here that would tie the use of "instancetype" to the "request" which is the receiver in the enclosing message expression.
Another problem is that C's expression parsing is bottom up. The block literal gets type checked before the enclosing message expression does. This means the expression for "request" gets type checked independently from the block literal. This is just fundamentally how C works.