Dynamic binding seems like a lie
Asked Answered
T

3

6

Objective-C uses dynamic binding: that is method calls are resolved at runtime.

Fine.

And use of dot notation really boils down to a method call

But, why then, can't I do something like this:

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];


  // Intercept the exception
  @try
  {
    @throw [ NSException 
            exceptionWithName:@"Exception named ME!" 
            reason:@"Because i wanted to" 
            userInfo:nil ] ;
  }
  @catch( id exc ) // pointer to an exception object?
  {



    //NSLog( @"%@ : %@\n", exc.name, exc.reason ) ; // ILLEGAL:  Request for member 
    // 'name' in something not a structure or union..
    // If objective-c uses dynamic binding, and dot notation
    // boils down to calling the getter, then
    // WHY do I have to cast to the concrete type here?

    // Only works if I cast to the concrete type NSException*
    NSException* nexc = (NSException*)exc ;
    NSLog( @"%@ : %@\n", nexc.name, nexc.reason ) ;



  }



  [pool drain];
    return 0;
}

When I hear "dynamic binding" I'm thinking "so it should behave like a scripting language", and I'm surprised how inflexible Objective-C seems compared to a scripting language like JavaScript.

Terri answered 8/11, 2009 at 17:1 Comment(4)
You're confusing dynamic binding with cake. The cake is a lie.Coreycorf
"Method calls are resolved at runtime" should really be thought of as "message dispatching occurs at runtime". The whole dot operator usage is more of a hack than anything else.Adrianadriana
There is nothing hackish about it; it is a very well defined synonym for a method call with one additional constraint that the type must be well known. (Whether or not one likes the dot or thinks it is a good addition is entirely opinion -- no comment :).Pessa
Saying that the dot operator isn't hackish because it's "very well defined" is like saying trigraphs aren't hackish because "they're very well defined by the standard." The reason(s) why you can do [(id)exc name], but you can't do (id)exc.name is one of the reasons why it's a hack, and a bad, poorly thought out one at that. Providing more than one way to do the same thing is usually a bad idea, and the fact that the two ways aren't symmetric causes lots of problems and confusion.Spermatium
M
17

You are confusing the runtime and the compiler. The runtime has no problem coping with that. The issue is that dot notation (which is syntactic sugar) requires type information for the compiler to disambiguate between Objective-C objects and C structs.

If you don't use dot notation it works:

NSLog( @"%@ : %@\n", [exc name], [exc reason]) ;

The above will generate a warning if the type is not id since the compiler knows it does know the type and can't guarantee the dispatch will work, but it will compile and run.

Fundamentally the issue at hand is the compiler needs to know whether to generate a structure load, or an Objective C dispatch, in other words, with dot notation it needs to have enough information to determine the difference between an object and a scalar type.

Milreis answered 8/11, 2009 at 17:9 Comment(0)
P
17

Dynamic binding is not synonymous with dynamic typing. C is a strongly typed language and, in particular, the type of an argument or return value is critical and can significantly impact code generation.

Properties are specifically designed to eliminate ambiguity. As a part of that, the decision was made to not allow the dot syntax to be used against id.

Specifically, it addresses this situation:

@interface Foo
- (short) length;
@end

@interface Bar
- (unsigned long long) length;
@end

Given the above in two separate header files, compilation of [anObject length] will give a warning only of both header files have been imported. If only one header file has been imported, then the call site will be compiled returning the type seen in the header. If the call site were for the other method, a very unexpected result would be returned.

The limitation on the dot syntax eliminates this potential ambiguity. This is also the reason why you don't generally see co-variant declarations of methods. The C ABI just doesn't support it cleanly (with that said, Objective-C does a poor job of supporting object type co-variance).

In reality, Objective-C developers rarely use the id type. Specific type declarations enable the compiler to significantly improve its code validation.

Pessa answered 8/11, 2009 at 17:16 Comment(1)
Excellent answer as usual, Bill! It's always nice to know about details of design decisions. And I agree, I use id sparingly, since I often prefer the benefits of static typing when I can get it.Murial
C
0

Objective-C does support dynamic binding. However, you cannot use properties on objects of type 'id' - but you can send it any messages you want. (This is probably a mistake in the current definition/implementation ... but let's leave that aside for now.)

If you did

NSLog(@"%@ : %@", [exc name], [exc reason] ); 

then it would work. Note that you don't need to put a newline on an NSLog statement, as they're all on separate lines anyway.

Coal answered 8/11, 2009 at 17:8 Comment(2)
Make sure you read bbum's answer. The implementation is not a mistake, but on purpose.Holography
Fair enough, must have answered around the same time :-)Coal

© 2022 - 2024 — McMap. All rights reserved.