Foundations of Objective-C André Peng -- Get out a piece of paper Write a factorial function. Use whatever language you like Don't cheat int fact(int n) { /* Write your code here */ } fact(3) = 3 * 2 * 1 == 6 fact(4) = 4 * 3 * 2 * 1 == 24 fact(5) = 5 * 4 * 3 * 2 * 1 == 128 fact(0) = 1 -- What is an object? int i; i = 0xdeadbeef [de][ad][be][ef] -- typedef struct _IntContainer { int i; } IntContainer IntContainer ic; ic.i=0xdeadbeef; [de][ad][be][ef] -- What is an object? typedef struct _NSPoint { CGFloat x; CGFloat y; } NSPoint; NSPoint p; p.x = 1.0; p.y = 2.0; [3f][80][00][00][00][40][00][00][00] x y -- int *pi; *pi = 0xdeadbeef; pi [08][03][91][70] 0x08039170 [de][ad][be][ef] -- struct NSObject { Class isa; } -- struct NSObject { struct objc_class* isa; } struct objc_class { Class isa; Class super_class; const char* name; long version; long info; long instance_size; struct objc_ivar_list *ivars; struct objc_method_list **methodLists; struct objc_cache *cache; struct objc_protocol_list *protocols; } (gdb) p NSApp $2 = (struct objc_object *) 0x8039170 (gdb) p *NSApp $3 = { isa = 0x15f8e0 } (gdb) p NSApp->isa $4 = (struct objc_class *) 0x15f8e0 (gbd) p *NSApp->isa $5 = { isa = 0x160de0, super_class = 0x22d3a0, name = 0x1322de "RWApplication", version = 0, info = 12206145, instance_size = 100, ivars = 0x169720, methodLists = 80391e0, cache = 809d710, protocols = 15b064 } -- @interface NSObject { class isa; } @interface MySubClass : NSObject { int i; } @interface MySubSubClass : MySubClass { float f; } struct NSObject { Class isa; } struct MySubClass { Class isa; int i; } struct MySubSubClass { Class isa; int i; float f; } -- Messaging -- @implementation NSMutableString (void) appendString:(NSString*)aString { ...; } @end => void | NSMutableString appendString:|(id self, SEL _cmd, NSString* aString) { ...; } -- % nm /usr/lib/libSystem.dylib | grep strcmp 06093b0 T _strcmp nm Foundation.framework/Foundation | grep NSString compare 0C02bbf0 t -|NSString compare:| 0C06c200 t -|NSString compare:options| 0C00d480 t -|NSString compare:options:range| 0C00d4e0 t -|NSString compare:options:range:locale:| -- I'm sorry that I long ago coined the term "objects" for this topic because it gets many people to focus on the lesser idea. The big idea is "messaging". - Alan Kay -- http://www.paulgraham.com/power.html -- UNIFORMITY IS POWER -- for(int i = 0; i<=10; i++) { NSLog(@"%d", i); } 1 to:10 do:[:i| Transcript show: (i asString); ]. -- Everything is an object, including code. Messaging is the exclusive means of object communication. -- if (x < y) { foo; } else { bar; } (x < y) ifTrue: [ foo ] ifFalse: [ bar ] -- Simpler to reason about Simpler to implement Re-think the problem -- NSArray* array = ...; |array do:^(id obj){ NSLog("%@", obj) }]; |NSThread performOnMainThread:^{ ... }] |array pdo:^(id obj){ NSLog("%@", obj) }]; -- Alonzo & Alan & Stephen & Kurt. -- f(x) = x * 2 f(3) == 6 λ x. x * 2 λ (x. x * 2) 3 == 6 -- x λ... (λ...) y -- 0 := λ f x. x 1 := λ f x. f x 2 := λ f x. f (f x) 3 := λ f x. f (f (f x)) PLUS := λ m n f x. n f (m f x) MULT := λ m n f. n (n f) TRUE := λ x y. x FALSE := λ x y. y AND := λ p q. p q p OR := λ p q. p q p NOT := λ p a b. p b a IFTHENELSE := λ p a b. p a b PAIR := λ x y f. f x y FIRST := λ p. p TRUE SECOND := λ p. p FALSE NIL := λ x. TRUE NOTNIL := λ p. p (λx y. FALSE) -- Get out a piece of paper Write a factorial function. Use whatever language you like Don't cheat int fact(int n) { /* Write your code here */ } fact(3) = 3 * 2 * 1 == 6 fact(4) = 4 * 3 * 2 * 1 == 24 fact(5) = 5 * 4 * 3 * 2 * 1 == 128 fact(0) = 1 -- int fact(int n) { int result = 1; int i; for(int i=0; i<=n; i++) { result *=i; } return result; } int fact(int n) { if (n == 0) return 1; else return n * fact(n-1); } -- Though OOP came from many motivations, two were central... the small scale one was to find a more flexible version of assignment, and then try to eliminate it altogether. - Alan Kay Assignment statements - even abstract ones - express very low-level goals, and moreof them will be needed to get anything done. Generally, we don't want the programmer to be messing around with state, whether simulated or not. - Alan Kay -- Pure functions Give the same output when given the same inputs Have no observable side-effects -- f(x) = x * 2 f(string) = newString -- Pure functions Are far, far easier to reason about (i.e. maintain!) Are far more composable than objects+methods They are more uniform They are smaller Naturally concurrent -- Lessons for Objective C Minimal state, in both methods and objects Every |var you add is a burden Design your data so that invalid state is impossible Use const liberally in methods Prefer immutable objects over mutable -- Lessons for Objective C If you need a comment to explain something, move the code into a new function Search for uniformity, in data design and method calls -- Thanks! André Peng W http://algorithm.com.au E ozone@algorithm.com.au T http://twitter.com/andrepang