iT邦幫忙

1

Identity? of objects (SICP lec5b)

计算机程序的构造和解释(Lec5b:计算对象) ,整個影片都很值得看,但這篇要說的是從 46:35左右開始講的,後面參雜了一點 lec6a。

最近開始學Clojure,所以內容中操作的部分會用clojure來呈現

任何的一個object的最小單位就是一個pair,而如何組成pair這個data structure呢,就是利用 cons , (cons x y) 就是一個pair。

對於任何的 x, y
(car (cons x y)) = x
(cdr (cons x y)) = y

但其實上述定義並沒有闡述,到底cons是否有像人一樣的身份(identity)?

未引入賦值

就上述的定義來說,其實是一種抽象,cons包含兩個參數,如果兩個cons包含的參數是一樣的,那這兩個cons就是一樣的。

引入賦值後

上述定義就不完整了,因為如果我想修改兩個包含一樣參數cons的car,那兩個cons都同時會被我修改嗎?

如果兩個cons代表的是數學,那其實沒差,就算是兩個一樣的 3/4,就還是3/4,變成同把兩個3/4變成1/4,反正就是1/4,並沒有所謂 身份 的區別,

但物件導向的世界中,我們描述的是真實的世界,是有 身份 的,改變car可能就像是做變性手術一樣der。

何謂身份:

(def a (cons 1 2))

這是說我在一個環境裡面,創造了一個名為 a 的 pair,這個pair裡面包含兩個指針一個指向1,一個指向2。

接下來,我又定義了一個 b (def b (cons a a))

那 b 這個pair指向的兩個a,是同一個a嗎? 且現在呼叫 a 的方式有三種 a, (car b), (cdr b) ,哪個才是真正的呢?

而現在我用了 賦值去改 car b (set-car! (car b) 3) ,原本存在 a 的 1被改成3了。

現在如果再呼叫 (car a) 回傳的會是 3,儘管一開始我們定義的 (car a) 是1。

非預期的共享,是大型系統的bug來源,透過給object一個身份 ,給它一個別名互相共享,是有蠻多方便,但也相對付出了代價。

演示一下用lambda憑空製造一個 cons ! by Alonzo Church

(defn cus-cons [x y] (fn [fc] (fc x y)))
(defn cus-car [fc2] (fc2 (fn [a d] a)))
(cus-car (cus-cons 1 2)) ;=> 1

演繹一下這個神奇的程序

  • 1, 2被代換掉 cus-cons中的x, y,回傳了一個function (fn [fc] fc 1 2)
  • 傳入 cus-car之後代換掉 fc2 : ((fn [fc] fc 1 2) (fn [a d] a))(fn [a d] a) 被當成參數代換掉 fc
  • 最後變成 ((fn [a b] a) 1 2) ,回傳值就是1了,超級神奇吧!

set 設計

稍微修改一下 church的算式

(defn cus-cons
  [x y]
  (fn [fc]
    (fc x
        y
        (fn [n] (let [x n]))
        (fn [n] (let [y n])))))
(defn cus-car [fc2] (fc2 (fn [a d sa sd] a)))
(defn cus-cbr [fc2] (fc2 (fn [a d sa sd] d)))
(defn cus-set-car! [fc2 x2] (fc2 (fn [a d sa sd] (sa x2))))
(defn cus-set-cdr! [fc2 y2] (fc2 (fn [a d sa sd] (sd y2))))

在cons的地方,新增兩個lambda參數作為修改的認證用,這個set理論上是可行的,而有了一個set,就可以做千千萬萬個set了

Lambda這個方式,完全是用function來完成 cons car cdr,並沒有存在任何一的地方,真的很有趣啊,之後一定要來看一下 這個傳說中的 Alonzo church lambda calculus!!!

總結

回到賦值與state的討論,當開始任意使用賦值,以下問題便開始產生

  • Change: 變數不再代表一個值,可能會被改變
  • Time: 函式的回傳值,可能會因為時序的不同而不一樣
  • Identity: pair不再只是用car cdr去呼叫,它可以有別稱
  • Share: 兩個別稱之間有可能會共享同一個pair

有這麼多問題產生,為何要這麼做?
因為想構造 模塊化 modularity的系統,對應真實世界的模型,而也許我們對於真實世界有些誤解,也許時間只是一個幻覺,並不會改變什麼,也許不用把時間切成一點一點分開看待,更宏觀的來看成一個"時空"的路徑。

如何解決:回到數位電路模擬器,可以以訊號處理的角度,而不是以單一時序的角度來看,如何做呢? 請繼續看下去


尚未有邦友留言

立即登入留言