將劇本以 @-exp 改寫後,我發現 macro 的重要性。以下是我劇本的一個片段:
@novel["家變"]{
@room["書房"]{
@scene["牆壁"]{
你面對一面白色牆壁。牆壁上有條裂縫。向上直達天花板。
@next["檢查裂縫" #:scene "裂縫"]
@next["檢查天花板" #:scene "天花板"]
}
@scene["天花板"]
天花板有點潮溼。
}
@scene["裂縫"]{
裂縫中有隻螞蟻。
}
}
}
面對這樣的劇本,有兩種作法:
- novel 是 scheme function。此時,因為 room 會比 novel 早執行,因此,在執行 novel 前必須先建造一個名為 current-novel 的物件,或是使用一個 global 的物件,以存放 room 產生的資料。這使得劇本必須做小修改,而撰寫劇本的人,很可能不是一位程式設計師,必須操心這些小修改。
- novel 是 scheme macro。由於使用 macro,可以將建造 current-novel 的工作包括在 macro 的設計中,因此,撰寫劇本的人就不必操心這些問題。
在設計劇本的描述語言時,我也感受到 scheme 的 keyword 帶來的好處,以以上的劇本為例,在 next 中我使用了 #:scene 這個 keyword,它使得劇本更容易閱讀。
一個讓我驚訝的事是,我目前感受不到 PLT-Scheme 的 define-struct 的好處。原本我使用 (define-struct novel (name)) 來建立 novel 這結構,但最後我改成如同我原本使用 javascript 的作法,使用 hashtable,同時參考 SICP 的作法 來解決。
沒有留言:
張貼留言