• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Interpretation of static types in Cocoa [Was: Immutable discomfort]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Interpretation of static types in Cocoa [Was: Immutable discomfort]


  • Subject: Interpretation of static types in Cocoa [Was: Immutable discomfort]
  • From: Philippe Mougin <email@hidden>
  • Date: Fri, 19 Dec 2003 16:56:40 +0100

>> If you define your API to accept an immutable object (aka NSArray)
>> then folks should either give you an immutable object or mutable
>> one but abstain from changing anything in it.
>
> Actually, doesn't taking an NSArray as an argument imply that the
> the method won't change it (not that the caller isn't free to
> pass in an NSMutableArray?)

Well, I've seen some people using or advocating such conventions, including some skilled Cocoa engineers at Apple.

For instance, I've seen it expressed, quite clearly, like that:

----- quote ----
"In Cocoa, the types declared for arguments and return values in the API are more about what the caller can do with the return value or what the method will do with the argument rather than what the return value really will be or what the argument must be."
------------------

However, in the spirit of good technical debate, I'd like to state it that, IMHO, these conventions are bad and should not be used. They leads to numerous problems, including the fact that, AFAIK, they go against decades of research and refinement in the definition and interpretation of type systems by the whole object-oriented programming community.

In the spirit of "programming by contract", which provides us with a reasonably good and well known model for the interpretation of types in Objective-C, the type of an argument should be interpreted as a precondition (i.e., a requirement that the caller must respect). It should NOT be interpreted as a promise made by the method that it will consider the static type to be the *exact* type of the argument. Thus, if a method declares, using static typing in its signature, that it takes an argument typed as NSArray, this should not be interpreted as a promise that the method will not modify the NSArray. Form the point of view of the caller, it should be interpreted as a requirement for it, in order to fulfill its "contract", to pass an instance of NSArray or of a subclass of NSArray. No more, no less.

As you know, NSArray, *considered as the specification of an abstract data type*, do not imply immutability (the best proof for that is the existence of a mutable subclass, NSMutableArray). At run-time, it is perfectly acceptable (as far as the type system is concerned) for the invoked method to determine that the actual argument is in fact an instance of NSMutableArray and to modify it.

Likewise, the statically declared return type of a method should be interpreted as a promise the method makes to its caller regarding the actual class (or superclass) of the returned object. It should NOT be interpreted as a requirement the method impose on its caller about what the latter should consider to be the *exact* type of the returned object, and thus should/should not do with the returned object.

The correct way for asking/enforcing some code (a method we call or a caller we give back an object) to follow some behavior regarding a specific object is not to defines weird conventions, that are incompatible with the otherwise generally accepted interpretation of the type system, and are impossible to generalize (at least, if these convention could be generalized to the point of providing a complete and consistent alternative interpretation of the type system, then the terms of the debate could be different, but it is not the case). IMO, The correct way is to provide it, *at run-time*, an object of a class that, as an abstract data type, defines (and possibly enforces) this behavior. Alternatively, or in complement, this can be specified by some specific documentation for the methods (like, for example, a sentence that states "the returned object must not be modified"). But doing it by corrupting the interpretation of the type system or introducing exceptions to this interpretation is not a good idea.

For a dynamically typed language like Objective-C this point should be even more obvious. What we can/should do with an object is primarily defined by the actual class (and state) of the object at run-time, not by the fact it was returned/passed, at some point in its lifetime, by/to a method that declare in its header to use such or such static type. Otherwise, we would have a hard time doing very useful things with objects coming from a method that declare returning an NSObject *, for example. Trying to interpret the static type of the arguments and return value as the *exact* type of the object which defines what some code should/should not do with the object is generally a dead-end in the context of a general purpose object-oriented language, because it rules-out downcasting. Trying to do that in the context of general purpose and primarily dynamically typed object language like Objective-C is even more strange.

I'd like to strongly advise anyone using Cocoa to stick to the well established approach described here when designing Objective-C classes. An approach that we find pervasively documented and used in other object-oriented languages and frameworks throughout the industry. Using conventions incompatible with it equals to giving up any hope in a reasonably sound, general and intuitive interpretation of our type system. This leads to unintuitive idioms, complexity, unintended limitations, inconsistent interpretation of the type system, and brittle code (and, if this is not enough, this might also make your car consume more oil ;-)

Best,

Philippe Mougin _______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.
  • Follow-Ups:
    • Re: Interpretation of static types in Cocoa [Was: Immutable discomfort]
      • From: Nat! <email@hidden>
    • Re: Interpretation of static types in Cocoa [Was: Immutable discomfort]
      • From: Glenn Andreas <email@hidden>
  • Prev by Date: Re: fonts - yet another desperate plea
  • Next by Date: Re: CGXRemoveTrackingArea problem
  • Previous by thread: SFAuthorizationView? Supporting 10.2 and 10.3
  • Next by thread: Re: Interpretation of static types in Cocoa [Was: Immutable discomfort]
  • Index(es):
    • Date
    • Thread