The message-eating nil is a built-in or optional feature of some programming languages that lets you ignore message execution on nil (or null) object. Objective-C does that. In SmallTalk, Ruby and some other languages you can add this behaviour in runtime.
Why is it useful: for instance, accessing person.address.street_name will simply yield nil if either person, address or street_name are nil. Another example is iterating nil instead of a list without checking if it is nil.
Some like message-eating nil because it saves a lot of boring code and helps avoiding some silly crashes. Others dislike the feature on the ground that it hides errors and makes it more difficult to reason about all the code paths.
However, here I present a definitive answer to the question whether your next programming language should or should not support message-eating nil.
Nil should be message-eating.
Here is why: when you switch from a language without message-eating nil to the language which has one, you only spend a week or two adapting to the new style and being puzzled from time to time where the hell the data is missing. After a longer period of time, you will change your style and find it useful and easy to program using this feature. But when you switch from such language to the one without message-eating nil, you will notice just how much useless if/then conditions are being added in your code. And when you forget adding one somewhere, you will get silly crashes in production code. Silly because you already know the nil would have been handled if it was allowed to be propagated.
Please, allow nil to eat messages.
PS. If you think of adding message eating to NilClass in Ruby, remember that metaprogramming can be dangerous.
Xcode 4.4 is capable of subscript syntax and allows migrating the code from [arr objectAtIndex:0] to arr[0]. A few tweaks needed, however:
1. While OS X 10.8 SDK already contains objectAtIndexedSubscript: and objectForKeyedSubscript:, iOS 5.1 SDK does not. To make compiler happy, you should add this:
#if __IPHONE_OS_VERSION_MAX_ALLOWED < 60000
@interface NSDictionary(IGSubscripts)
- (id)objectForKeyedSubscript:(id)key;
@end
@interface NSMutableDictionary(IGSubscripts)
- (void)setObject:(id)obj forKeyedSubscript:(id )key;
@end
@interface NSArray(IGSubscripts)
- (id)objectAtIndexedSubscript:(NSUInteger)idx;
@end
@interface NSMutableArray(IGSubscripts)
- (void)setObject:(id)obj atIndexedSubscript:(NSUInteger)idx;
@end
#endif
2. To deploy new stuff back to iOS 5 and iOS 4, you need ARCLite. Somehow ARC itself works without extra configuration, but subscripting requires explicit linker flag:
In project settings add to Other Linker Flags: “-fobjc-arc”
3. If you use Edit -> Refactor -> Convert to Modern Objective-C Syntax, it will replace -[NSLocale objectForKey:] with a square brackets syntax, which is not supported by NSLocale. This is the only bug I have found with the automatic translation. NSCache and NSUserDefaults are not touched by the migrator.