Categories


Archives


Recent Posts


Categories


Objective-C, Deeply Weird : Methods

astorm

Frustrated by Magento? Then you’ll love Commerce Bug, the must have debugging extension for anyone using Magento. Whether you’re just starting out or you’re a seasoned pro, Commerce Bug will save you and your team hours everyday. Grab a copy and start working with Magento instead of against it.

No Frills Magento Layout is the only Magento front end book you'll ever need. Get your copy today!

I’m teaching myself Cocoa and Objective-C via Aaron Hillegass’s Cocoa Programming for Mac (second edition). I’m using my website to talk through the process and review what I’ve just taught myself. This helps me learn. I will, over the next new months, inevitably tell many grievous lies. I’ll also be overusing the word apparently in an attempt to cover my ass. I’d like to apologize for both.

I’m finally taking some time to look into Cocoa and Objective-C, and have found the language deeply, deeply weird. Weird in the way that Javascript, the language, is also deeply, deeply weird. Sun and Java have, more or less, completely dominated how the average programmer thinks about OOP. Java has so heavily influenced the development of both C#’s and PHP5’s object model that it’s easy to forget some people had/have fundamentally different ideas about what objects are and how they should be used.

One (apparently core) concept that’s twisting my brain around is methods. You don’t call a method in Objective-C, you send the object a message. There’s also less of a distinct line between methods and their parameters. Let’s take a look at how methods are defined and used.

In PHP a parameterless method definition and call looks something like this

public function myMethod(){...}    
...
//we call the myMethod method of our object
$result = $myObject->myMethod()

In Objective-C a parameterless method definition and message send (call) looks something like this.

- (int) myMethod{...}
...
//we send our object the myMethod message
result = [someObject myMethod]

Big differences so far in Objective-C are

  1. Call vs. Message Sending
  2. The (int)
  3. The lack of public/protected/private
  4. The brackets

The Call vs. Message Sending semantics seem, on the surface, to be the same thing, but my book has promised me there are subtle, yet deeply important differences. The first I’ve encountered is, an object will accept messages that haven’t been defined (it silently ignores them) whereas Java/C#/PHP5 would yell at you for calling an undefined method. (Let’s pretend things like __call don’t exist for now)

The (int) is easy enough to understand. Objective-C is a superset of the C language. When you declare functions in C, you need to declare the type of the value that the function will return. In this case, we’re returning an int. If our method didn’t return a value, we would have used (void) instead.

The lack of public/private/protected; As I understand it, the Objective-C complier doesn’t have any concept of access levels. It is possible, hoverever, to create methods that behave in a private or protected way. Because of this, Cocoa applications tend to stress object composition over deeply abstracted object inheritance hierarchies and patterns. (Objective-C 2.0 has apparently added some level of support for access levels, but I’m deliberately learning from an older book so I know how we got here)

The brackets, frankly, are still a bit of a mystery to me. They obviously group the object and its method, but their actual purpose/semantic meaning still eludes me. I assume this will start to look “correct” to me at some point. When I first encountered the arrow (->) operator back in college c++ class it looked equally weird. For now I still have to consciously think when I see the brackets to get my head in the “object on the left, method on the right” mode. This becomes more complicated when we get to multiple parameters.

Let’s add a single parameter to our method. In PHP

public function myMethodAtIndex($param1){...}
...
$myObject->myMethodAtIndex($someVariable)

And Objective-C. Note: We’ve changed out method to return nothing (aka. void)

- (void) myMethod:(int)param1
...
[myObject myMethod:someVariable]

So, big differences here

  1. The (int) in front of our parameters
  2. The colon (:)

Again, number one proves easy to explain. You need to let the complier know what type each parameter is. All variables in Objective-C (and C proper) need to be declared with types.

The colon is part of the method name (the method name is also known as a selector), and indicates it’s a method that accepts parameters.

So, let’s add a second parameter to our method and break our heads. For reasons that will become apparent later, we’ve changed our method name to be myMethodAtIndex.

In PHP

public function myMethodAtIndex($param1,$param2){...}
...
$myObject->myMethodAtIndex($someVariable,$someOtherVariable)

And now, Objective-C.

- (void) myMethod:(int)param1 atIndex:(double)param2
[myObject myMethod:someVariable atIndex:someOtherVariable]
//this syntax is also valid
[myObject   myMethod:someVariable 
            atIndex:someOtherVariable]

Right now, when my brain sees this syntax, it’s the code equivalent of that Mike Huckabee double eyes picture.

So, this looks sort of like named parameters, but it’s actually something else. The method name/selector is myMethod:atIndex:. Parameters are passed into a method by associating them with specific selector sections.

If you’ve learned how to program using dynamic languages (perl, PHP, Javascript, etc.) there’s a tendency to mentally separate methods/functions and their parameters. A function has a name, a function has parameters. These are two different things.

The reality is, from a capital C, capital S Computer Science standpoint, functions/methods and their parameters are closely linked. Together they form the prototype/signature of that function, which is important when you’re compiling the program to assembly and/or machine code. Apparently.

This is less weird to you if you’re a Java programmer, which still has hints of Computer Science on the surface. For example, if you want to define a method with optional parameters in Java, you need to define multiple methods with the different numbers of parameters. This hints that something cares about the relationship between a method’s name and it’s parameters

public int methodName(){
    //not sure if you need keyword "this" here, I'm not a java programmer.
    this.methodName(-1);    
}

public int methodName(int myParam){
    ...
}

Compare to PHP,

public function methodName($myParam=-1){
    ...
}

The longer I program the more I’m interested how a language designer’s fundamental Computer Science philosophies end up influencing the semantics of their language, semantics that day-to-day programmers come to rely on and understand without actually understanding why they’re using something the way they are. If you’re bored, try applying this concept to actual human languages (I wouldn’t recommend doing so without large quantities of high quality pharmaceuticals)

Once I spend some time writing Objective-C code and wrap my head around this, I’m sure I’ll cringe whenever I return to a language with a vague, semantic-less list of parameters. Right now though I’m trying to un-learn 10+ years of assumptions and habits and it’s deeply deeply weird.

Originally published October 4, 2008