Re: [Pyobjc-dev] Calling methods on nil
Brought to you by:
ronaldoussoren
From: <bb...@ma...> - 2003-05-11 21:20:14
|
On Sunday, May 11, 2003, at 11:49 US/Eastern, Marcel Weiher wrote: >> Having done ObjC development since 1989 -- 4 or 5 years prior to >> diving into Python -- you might be surprised to learn that I very >> strongly prefer the behavior of Python's (and Java's) 'message to nil >> throws' behavior vs. ObjC's 'message to nil silently eaten'. > > Having done ObjC development since 1987, I much prefer the coding > simplicity the current behavior gives, while I don't recall the > problems you report being anything but an extremely rare occurrence. Difference in experience then -- I have spent a good part of my career mentoring teams to help them achieve success. This is typically done in environments where the project is under "schedule stress". More often than not a major source of stress is "strange or intermittent failures". If you have a construct like... [[[[foo bar] baz] bob] fred]; ... and any one of -bar, -baz, -bob, or -fred unexpectedly returns nil when it shouldn't, debugging is a nightmare. >> When everything is working correctly 'message to nil silently eaten' >> is a great convenience. When something somewhere unexpectedly >> returns nil, it becomes an incredibly nasty pain to try and figure >> out exactly where the problem might be. By the time it crops up, >> you may be many cycles through the run loop away from where the >> problem actually is. > > Hmmm...this sounds like you are working too much with mutable state, > in which case nils are just one symptom, and doctoring about with this > one symptom is just hiding the deeper problems. If you move away from > mutable state, you will also find that you don't have problematic > values (of which nil is just one prominent example) causing problems > when the cause of the problem (of the problematic value) has long > since disappeared from the call-stack. > > If you use a more "functional" programming style, pulling values and > evaluating expressions when needed instead of pushing values and > stashing computed values, you will likely find that you don't get this > type of problem-propagation. No -- that is not the problem. There is the potential for the problem to arise *anywhere* a method is invoked/called/messaged where the developer has not previously validated that the target is non-nil. If, for whatever, reason-- misconnection in IB, service mysteriously down, data integrity damage-- the target is nil, no error will occur upon method invocation and the fact that said object reference was nil will now cause a problem that may be considerably separated from the actual source of the problem. >> Over the last-- jeez, nearly 15 years-- I have seen novice and >> experienced developers-- myself included-- waste many many hours >> trying to track down a problem that turned out to be an unexpected >> nil. Going with a 'message to nil raises' model may have required >> the addition of quite a few extra if () statements here and there >> over the years, but that route would have considerably decreased the >> frustration factor for quite a large number of developers. > > While I don't question your personal experience, I do believe that the > problem may lie elsewhere. > > Also, I believe very strongly in "intention-revealing" code. That is, > the code should reflect the problem, not the technology. Things like > constant checking of types/nil-values/exceptions typically have > nothing to do with the problem domain, and do little but obscure the > solution. I certainly notice that my Java code is a lot more verbose > and a lot less maintainable than my Objective-C code. It would seem that "intention revealing" would mean writing code that shows that the developer intended to deal with the fact that something could potentially be nil in a valid situation by actually checking for it. [[[[foo bar] baz] bob] fred]; The above does not reveal the developers intentions in this regard -- maybe the developer fully expects -baz and -fred to return nil and that's OK -- but -bar and -bob returning nil is something the developer never intended to have happen. If an exception were thrown in such a case, the above would change to: id x; x = [[foo bar] baz]; if (!x) return; x = [[x bob] fred]; if (!x) return; The above is a few more lines of code, but the developer's intentions are exactly revealed. b.bum |