SlideShare a Scribd company logo
Immutability
                          Yung-Luen Lan




Friday, August 10, 12
我是誰?

                        • 藍永倫 @yllan
                        • 前 CocoaHeads Taipei Organizer.
                        • 寫過 (Open Source) Cocoa App.


Friday, August 10, 12
Friday, August 10, 12
我以為 OSS 是這樣




Friday, August 10, 12
實際上得到的:
                   “堂堂⼀一個⽐比⼀一搬⼈人聰明的電腦程式設計師, 還是 Mac程式 ⼯工程師, 竟然講話 像
                   是 在⼆二⼿手煙密佈的骯髒網咖裡⾯面打電動玩具的 ⼩小混混講的話.

                   真的令⼈人不敢領教, 真的是 讓⼈人很遺憾!! 堂堂⼀一個 Mac OS 軟體設計⼯工程師, 竟
                   然還說:我如果⼼心地很壞, 妳問我, 我會⽼老實回答嗎?

                   幹XXXXX 他⾺馬的, 我真的很⽣生氣, 很⽣生氣~~~ 竟然⼀一個程式設計師的⽔水準是
                   這樣的.”




                  “幹林勞奧”

                  “我⾮非常 90%肯定 他的軟體 不安全!!! 請⼤大家 ⾃自⼰己⼩小⼼心!!!
                  不是 每⼀一個電腦⼯工程師 都是 正派的!!”




Friday, August 10, 12
Friday, August 10, 12
在主題
                        開始前
Friday, August 10, 12
壹
Friday, August 10, 12
警告
Friday, August 10, 12
Slides 裡的
                           code
                         都是錯的

Friday, August 10, 12
貮
Friday, August 10, 12
Friday, August 10, 12
immutable |iˈmyo͞otəәbəәl|
             adjective
             unchanging over time or unable
             to be changed: an immutable fact.


Friday, August 10, 12
無法
Friday, August 10, 12
                        修改
安全
                 第一
Friday, August 10, 12
Change
Friday, August 10, 12
char *p = "hello";
                        p[0] = 'c';
                        // GOTCHA!



Friday, August 10, 12
- (void) setUsers: (NSArray *)users
    {
      if (users != _users) {
        [_users release];
        _users = [users retain];
      }
    }

    - (NSArray *) users
    {
      return _users;
    }

Friday, August 10, 12
CocoaHeads *ksBranch = [CocoaHeads new];

 NSMutableArray *people = [NSMutableArray
 arrayWithObjects: @"mikimoto", …, nil];

 [ksBranch setUsers: people];

 [people addObject: @"yllan"]; // BAD!




Friday, August 10, 12
MUTABLE




Friday, August 10, 12
Immutable in Cocoa

                        • NSArray
                        • NSDictionary
                        • NSSet
                        • NSString
                        •…

Friday, August 10, 12
Mutable in Cocoa

                        • NSMutableArray
                        • NSMutableDictionary
                        • NSMutableSet
                        • NSMutableString
                        •…

Friday, August 10, 12
init for Immutable

                        • 在 init 時就給定初始值。
                        • 到被 dealloc 前都無法修改。
                        • 像物件版的 const!


Friday, August 10, 12
+ (id) classnameWithData: (id)data

                 - (id) initWithData: (id)data




Friday, August 10, 12
沒有
Friday, August 10, 12
                        用?
Derivation

Friday, August 10, 12
- (id) arrayByAddingObject:



                Array1




               Array2



Friday, August 10, 12
// init
           + (id) classnameWithData: (id)data
           - (id) initWithData: (id)data

           // derive
           - (classname *) classnameByDoSomething…




Friday, August 10, 12
也要有Mutable

Friday, August 10, 12
// init
       + (id) classnameWithData: (id)data
       - (id) initWithData: (id)data
       // derive
       - (classname *) classnameByDoSomething…


      @interface MutableClassname : Classname

      // modify
      - (void) doSomething…




Friday, August 10, 12
CocoaHeads *ksBranch = [CocoaHeads new];

 NSMutableArray *people = [NSMutableArray
 arrayWithObjects: @"mikimoto", …, nil];

 [ksBranch setUsers: people];

 [people addObject: @"yllan"]; // BAD!
                          NSMutableArray 也是
                             NSArray!




Friday, August 10, 12
Copy
Friday, August 10, 12
NSArray *a = [NSArray new];
        NSMutableArray *mA = [NSMutableArray new];

        NSArray *b = [a copy];
        NSMutableArray *mB = [mA copy];

        [a arrayByAddingObject: @"Hello"];
        [mA addingObject: @"Hello"];

        [b arrayByAddingObject: @"Hello"];
        [mB addingObject: @"Hello"];




Friday, August 10, 12
NSArray *a = [NSArray new];
        NSMutableArray *mA = [NSMutableArray new];

        NSArray *b = [a copy];
        NSMutableArray *mB = [mA copy];

        [a arrayByAddingObject: @"Hello"];
        [mA addingObject: @"Hello"];

        [b arrayByAddingObject: @"Hello"];
        [mB addingObject: @"Hello"]; // DAMN!




Friday, August 10, 12
copy: immutable version

                 mutableCopy: mutable version




Friday, August 10, 12
@interface Classname <NSCopying,
      NSMutableCopying>
      // init
      + (id) classnameWithData: (id)data
      - (id) initWithData: (id)data
      // derive
      - (classname *) classnameByDoSomething…

      // copy
      - (id) copyWithZone: (NSZone *)zone
      - (id) mutableCopyWithZone: (NSZone *)zone




Friday, August 10, 12
細節
Friday, August 10, 12
不用真的
                        copy!


Friday, August 10, 12
immutable 的話
                        只要 retain 就好!


Friday, August 10, 12
Heavy RotationDerivation?




Friday, August 10, 12
- (id) arrayByAddingObject:



                Array1




               Array2



Friday, August 10, 12
Persistent Data
                          Structure
                        come to the rescue!

Friday, August 10, 12
m



                        43
Friday, August 10, 12
m   n



                        44
Friday, August 10, 12
m   n



                        45
Friday, August 10, 12
m   n



                        46
Friday, August 10, 12
m   n



                        47
Friday, August 10, 12
優點

                • 部分更新,省時間 O(lg n)
                • 共享結構,省空間
                        n + k O(lg n) with k derivation
                • ⾃自然擁有歷史紀錄

Friday, August 10, 12
缺點


                        • Pointer 造成 overhead
                        • 對 CPU cache 較不友善


Friday, August 10, 12
Mutable ↔ Immutable

                                              Mutable   Immutable
                                    Convert
                                              Update      Derive

      Immutable backed by Mutable
      @interface MyArray {
          NSMutableArray *_array;    O(n)      O(1)       O(n)
      }


      Mutable backed by Immutable
                                               O(n)       O(n)
      @interface MyMutableArray {
                                     O(1)
      }
          NSArray *_array;
                                              O(lg n)    O(lg n)


                                      50
Friday, August 10, 12
[] is fast.

Friday, August 10, 12
⽐比你想得複雜
                        • http://ridiculousfish.com/blog/posts/
                          array.html




                                             52
Friday, August 10, 12
Friday, August 10, 12
問題?
Friday, August 10, 12

More Related Content

Immutability

  • 1. Immutability Yung-Luen Lan Friday, August 10, 12
  • 2. 我是誰? • 藍永倫 @yllan • 前 CocoaHeads Taipei Organizer. • 寫過 (Open Source) Cocoa App. Friday, August 10, 12
  • 5. 實際上得到的: “堂堂⼀一個⽐比⼀一搬⼈人聰明的電腦程式設計師, 還是 Mac程式 ⼯工程師, 竟然講話 像 是 在⼆二⼿手煙密佈的骯髒網咖裡⾯面打電動玩具的 ⼩小混混講的話. 真的令⼈人不敢領教, 真的是 讓⼈人很遺憾!! 堂堂⼀一個 Mac OS 軟體設計⼯工程師, 竟 然還說:我如果⼼心地很壞, 妳問我, 我會⽼老實回答嗎? 幹XXXXX 他⾺馬的, 我真的很⽣生氣, 很⽣生氣~~~ 竟然⼀一個程式設計師的⽔水準是 這樣的.” “幹林勞奧” “��⾮非常 90%肯定 他的軟體 不安全!!! 請⼤大家 ⾃自⼰己⼩小⼼心!!! 不是 每⼀一個電腦⼯工程師 都是 正派的!!” Friday, August 10, 12
  • 7. 在主題 開始前 Friday, August 10, 12
  • 10. Slides 裡的 code 都是錯的 Friday, August 10, 12
  • 13. immutable |iˈmyo͞otəәbəәl| adjective unchanging over time or unable to be changed: an immutable fact. Friday, August 10, 12
  • 15. 安全 第一 Friday, August 10, 12
  • 17. char *p = "hello"; p[0] = 'c'; // GOTCHA! Friday, August 10, 12
  • 18. - (void) setUsers: (NSArray *)users { if (users != _users) { [_users release]; _users = [users retain]; } } - (NSArray *) users { return _users; } Friday, August 10, 12
  • 19. CocoaHeads *ksBranch = [CocoaHeads new]; NSMutableArray *people = [NSMutableArray arrayWithObjects: @"mikimoto", …, nil]; [ksBranch setUsers: people]; [people addObject: @"yllan"]; // BAD! Friday, August 10, 12
  • 21. Immutable in Cocoa • NSArray • NSDictionary • NSSet • NSString •… Friday, August 10, 12
  • 22. Mutable in Cocoa • NSMutableArray • NSMutableDictionary • NSMutableSet • NSMutableString •… Friday, August 10, 12
  • 23. init for Immutable • 在 init 時就給定初始值。 • 到被 dealloc 前都無法修改。 • 像物件版的 const! Friday, August 10, 12
  • 24. + (id) classnameWithData: (id)data - (id) initWithData: (id)data Friday, August 10, 12
  • 27. - (id) arrayByAddingObject: Array1 Array2 Friday, August 10, 12
  • 28. // init + (id) classnameWithData: (id)data - (id) initWithData: (id)data // derive - (classname *) classnameByDoSomething… Friday, August 10, 12
  • 30. // init + (id) classnameWithData: (id)data - (id) initWithData: (id)data // derive - (classname *) classnameByDoSomething… @interface MutableClassname : Classname // modify - (void) doSomething… Friday, August 10, 12
  • 31. CocoaHeads *ksBranch = [CocoaHeads new]; NSMutableArray *people = [NSMutableArray arrayWithObjects: @"mikimoto", …, nil]; [ksBranch setUsers: people]; [people addObject: @"yllan"]; // BAD! NSMutableArray 也是 NSArray! Friday, August 10, 12
  • 33. NSArray *a = [NSArray new]; NSMutableArray *mA = [NSMutableArray new]; NSArray *b = [a copy]; NSMutableArray *mB = [mA copy]; [a arrayByAddingObject: @"Hello"]; [mA addingObject: @"Hello"]; [b arrayByAddingObject: @"Hello"]; [mB addingObject: @"Hello"]; Friday, August 10, 12
  • 34. NSArray *a = [NSArray new]; NSMutableArray *mA = [NSMutableArray new]; NSArray *b = [a copy]; NSMutableArray *mB = [mA copy]; [a arrayByAddingObject: @"Hello"]; [mA addingObject: @"Hello"]; [b arrayByAddingObject: @"Hello"]; [mB addingObject: @"Hello"]; // DAMN! Friday, August 10, 12
  • 35. copy: immutable version mutableCopy: mutable version Friday, August 10, 12
  • 36. @interface Classname <NSCopying, NSMutableCopying> // init + (id) classnameWithData: (id)data - (id) initWithData: (id)data // derive - (classname *) classnameByDoSomething… // copy - (id) copyWithZone: (NSZone *)zone - (id) mutableCopyWithZone: (NSZone *)zone Friday, August 10, 12
  • 38. 不用真的 copy! Friday, August 10, 12
  • 39. immutable 的話 只要 retain 就好! Friday, August 10, 12
  • 41. - (id) arrayByAddingObject: Array1 Array2 Friday, August 10, 12
  • 42. Persistent Data Structure come to the rescue! Friday, August 10, 12
  • 43. m 43 Friday, August 10, 12
  • 44. m n 44 Friday, August 10, 12
  • 45. m n 45 Friday, August 10, 12
  • 46. m n 46 Friday, August 10, 12
  • 47. m n 47 Friday, August 10, 12
  • 48. 優點 • 部分更新,省時間 O(lg n) • 共享結構,省空間 n + k O(lg n) with k derivation • ⾃自然擁有歷史紀錄 Friday, August 10, 12
  • 49. 缺點 • Pointer 造成 overhead • 對 CPU cache 較不友善 Friday, August 10, 12
  • 50. Mutable ↔ Immutable Mutable Immutable Convert Update Derive Immutable backed by Mutable @interface MyArray { NSMutableArray *_array; O(n) O(1) O(n) } Mutable backed by Immutable O(n) O(n) @interface MyMutableArray { O(1) } NSArray *_array; O(lg n) O(lg n) 50 Friday, August 10, 12
  • 51. [] is fast. Friday, August 10, 12
  • 52. ⽐比你想得複雜 • http://ridiculousfish.com/blog/posts/ array.html 52 Friday, August 10, 12