(Warning: more non-FP content).
So I'm in an undisclosed location away from home specifically to spend a few quiet days focusing on programming. I had a goal to teach myself enough iOS programming to get a small demo app submitted to the app store by the end of the week. I'm not sure I'll manage that, but I'm learning. I have 3 relevant books with me: iOS Programming: The Big Nerd Ranch Guide (Third Edition, Second Printing, August 2012), by Joe Conway and Aaron Hilegass; Objective-C Programming: The Big Nerd Ranch Guide (Second Printing, January 2012), by Aaron Hillegass; and a much older book, Object Oriented Programming: An Evolutionary Approach (Reprinted with corrections August 1986), by Brad J. Cox. Brad Cox is the guy who created Objective-C, and although the language he describes in his book is not the same as modern Objective-C, I thought it might give me some insight into the language design. I own, but did not bring with me, a number of books on Smalltalk including the "blue book" (Smalltalk-80: The Language and its Implementation by Adele Goldberg and David Robinson). I wish I had brought it! But on the other hand, maybe it's best that I not go too far down a rabbit hole into the history of programming languages and the way language constructs are adopted over time by other languages -- even though it's one of my favorite subjects.
So far, I've worked through a few chapters of each. I'm not really here to write reviews of the books; let's just say they have their various strengths and weaknesses. But here are some thoughts on the process so far.
1. Learning Objective-C is a little frustrating (that's good, actually -- most languages are a LOT frustrating to learn).
1a. One of the fundamental strengths of C, as a kind of portable assembly language, is that almost everything about the behavior of your program is right on the surface. I don't mean that there aren't sometimes surprising behaviors. But as far as the usage of memory and the order of execution, C is pretty easy to reason about, with a few minor exceptions (for example, the switch statement implies that the compiler may create conditional tests whose order and number don't match exactly what is indicated in your source code).
1b. Objective-C hides some functionality in a way that C programmers may find disturbing. Those coming to it from another language might not even notice that this is an issue, since they might expect that the runtime is doing a lot of implicit things. Or they might not think about it at all.
1c. The syntax of Objective-C is a weird mash-up of Smalltalk and C. It has strange aesthetics.
1d. Nevertheless, it is pretty clear that Objective-C is an enormously pragmatic and highly successful language. Therefore, from the perspective of a language designer or someone who studies the history and design of programming languages, it would be an enormous mistake to dismiss it because of its hybrid design. By all accounts it is an extremely productive language once a certain level of expertise is achieved.
2. These books are not necessarily written for someone who knows other languages (such as C and C++) well, and that is also frustrating.
2a. The iOS Programming book uses language imprecisely here and there and it is driving me to distraction.
2b. This is not necessarily their fault; terminology is often only precise within a specific domain and has imprecise meaning or different meaning outside of that domain.
3. Now, some details.
3a. The sentence "The class acts as a factory that creates instances of that class." This needs a little unpacking. The language of "factories" seems to come from design patterns and is also big in .NET and enterprise-y Java as the concept of a factory method. But this sentence actually buries a few surprises for C++ programmers. The first is that classes are objects -- they actually have a distinct run-time representation. And instances have a different run-time representation than classes. This seems reminiscent of the concept of prototypes in languages like NewtonScript, Self, and Omega, where objects can inherit from other objects, but it is different as well, since in NewtonScript a prototype is just another instance of a fundamental container data structure, a frame. I'm not sure yet whether in Objective-C you can create a class at runtime, but I wouldn't be surprised.
3b. From Smalltalk: a method call is triggered by sending an object a message. This implies more run-time overhead than a function call, even a virtual function call from C++, although no doubt this has been highly optimized in the runtime. A message-sending expression can return a value. So, for example, it seems to be idiomatic Objective-C to create an object with a statement like
Object *obj = [[Object alloc] init]
This wraps up quite a bit of behavior: Object is used as a type for a simple pointer variable obj, and also as a reference to the runtime Object class object. Sending Object the alloc message returns a new instance of an object, which can then be used as the receiver for the nested message send, sending it the init message, which returns its receiver.
3c. This "message" is a distinct thing, and seems to either be the same as or closely related to a "selector." Syntactically a selector is something like "methodNamePart1:argument1Name:argument2Name" and a selector like this is compatible with a message-sending statement like "[receiver methodNamePart1: argument1Name: argument1 argument2Name: argument2]." This implies (but I have not seen clearly explained, yet) that the compiler has to break all that down and keep track of it. iOS Programming mentions "arguments interposed into the selector." This seems to be similar to using required keyword arguments as in Dylan which, I think, borrowed the idea from CLOS. I think the packed string with colon-separated selectors might be an innovation in Objective-C; I'm not certain.
3d. iOS Programming mentions that an expression like obj_p = nil "destroys the object and sets its instance variable to nil." If this is accurate, and they don't just mean that the object is "cut loose," this implies hidden run-time behavior that I would like to see explained much more fully.
3e. Sending a message to nil is apparently a no-op at run-time. This scares me a bit; won't that tend to hide a situation where we might actually want a crash?
3f. I like the extensions to printf format strings: %@ representing "any object," producing a string generated by calling the object's description method.
3g. I'm not sure I understand the need for NSNull, if the compiler can already wrap special run-time behavior around nil. But I don't claim to understand everything yet.
3e. Instance variables are not included in class objects. That's... interesting. It sounds a bit like how static methods and fields in a C++ class are available without creating an instance.
3f. Getters and setters are not created for you, and by convention (which can be important, apparently, for compatibility with code that uses introspection) are called set+instance var name and the instance var name. I have a great distaste for different things that have the same name.
3g. Some interesting bits and pieces to digest further, later: instance methods; initializers; id, isa, self, super, and the "designated initializer." iOS Programming talks about the importance of the designated initializer for some time, which is a shame because it also doesn't seem to explain in any way how you designate an initializer.
3h. Class names seem to be all in one namespace -- in other words, I don't see evidence of a real module system. I know from watching this process in other languages that it can be very difficult to retrofit a language with a module system later.
That's about all I've got for now. I'm sure it will make more sense as I press on, for better or worse!