2009年10月23日 星期五

Functional Programming

使用 PLT Scheme 撰寫遊戲至今,我完完全全體會到 functional programming 的表達力。在我的程式中,現在到處是 map 及 lambda。而且,setter 的使用也減少許多。
不過,我寫遊戲的方式是有點瞎子摸象方式的,沒什麼事先的設計規劃。完全是玩玩改改。目前這樣做的進展很快。但能持續到何時,可維護性如何,我還沒有把握。

2009年10月20日 星期二

Chat and Wiki for Scheme.

台灣很少有和 Scheme 這種語言有關的資訊。既然我目前使用 Scheme 做為我開發遊戲的語言,我就將這部落格做為我提供 Scheme 相關資訊的平台。

由於需要,我搜尋是否有以Scheme實現的 wiki ,發現了以下網頁。

http://practical-scheme.net/

在網頁中有個 WiLiKi 從開發的歷史來看,這 Wiki 從 2001 年到 2009 都有開發的活動。因此我粗淺地斷定這作者不會放棄這個 Wiki 軟體的開發,因此值得信賴。

在這網頁中還有個 chat room 的軟體,這也讓我頗感興趣。

2009年10月18日 星期日

Continuation Web Server works great!

將原本以 javascript 及 Helma NG 寫成的遊戲程式以 PLT Scheme 改寫,使用 PLT Scheme 的 Web server,我發覺 Scheme 的 continuation 真的是撰寫動態網頁的利器。使用 javascript 時,點選遊戲中某個容器的物件,必須將這物件的 id 變成網頁上連結的參數,這樣點選物件時才能將這 id 回傳給 server,server 才知道點選的是哪一個物件。這也使得網頁的設計和 model 密不可分。但是使用 continuation 時這件工作就省下來了。在網頁上的連結對應的就是處理那物件的 continuation。我在撰寫這部分程式時根本就很少關心網頁要傳什麼資料給 server 的問題。

Continuation 實在太神奇了!

2009年10月16日 星期五

Continuation or not continuation

在瞭解了 Continutaion 在 Web development 的應用後,我以為 continuation 只適用於部份的Web程式。這時,就不得不覺得 PLT Scheme 的文件中對不使用 continuation 的 Web development 方法討論太少了。

以下的文章反應了我的想法,也提供了另一種以 PLT Scheme 撰寫 Web applications 的 tutorial:

2009年10月15日 星期四

Model-View-Controller 及 Continuation II

重新思考 WEB 程式開發中使用 Continuation 和 Model-View-Controller 之間的關係。我決定回到物件導向設計的基礎,Robustness,不再勉強套用 MVC 這隻鞋子。為了 Robustness,Model/View/Controller 的區分還是有價值的。但是使用 Callback 及 Event-loop 實現 View 這個概念就不一定有價值。

Model-View-Controller 及 Continuation

PLT Scheme Web Server 是一種 Continuation based Web Server。HTTP 的 stateless 特性使得某類網路應用程式難以撰寫。而 Continuation 可以解決這類的問題。

但是初次接觸 Continuation based Web Server 的我對這種程式的寫法不無疑問。在當初以 javascript 及 Helma NG 撰寫我的遊戲軟體時,我採用的是 page oriented 的撰寫方式,這樣的撰寫方式很自然地和 Model-View-Controller 的理念對應。但是當我以 Continuation 來撰寫時,還摸索不出如何做到 Model-View-Controller 的方法。

以我游戲中的一個場景為例。這場景秀出一段文字,之後給玩家三個選項,玩家點了選項後會跑到另一個場景,因此網頁上和這選項對應的連結必須指出將要到哪一個場景。如果使用 Continuation,產生 html 的 function (View) 必須知道這連結要執行哪一個 function (Controller),以產生那個 function 的 continutaion。但這使得 View 必須知道 Controller。再者,如果那個被連結的 function 會使用到產生 html 的 function 的 local 資料或引數,則那被連結的 function 還必須在產生 html 的 function 的 local 中定義。結果 View 和 Controller 無法分開放在兩個不同的 modules。

在 GUI 還不盛行的時代,撰寫交談式程式的概念十分簡單,就是先印出問題等待使用者回答,使用者回答後再根據使用者的回答進行處理。GUI 的複雜度使得我們必須使用 MVC 這樣的概念。程式流程的控制權轉到了使用者的手裡。但至少 VIEW 和 Controller 都還在同一台電腦上,資料得以互通。到了網路時代,WEB 程式的撰寫更為困難,因為人機界面落在另一台電腦,在伺服端的程式並不知道使用者正在觀看哪一個畫面。當使用者下命令時,伺服端程式只能從 request 來猜出使用者的要求,沒有 continuation 的設計時,request 內只有這次要求的資料,看不出過去要求的歷史,無法處理複雜的,必須依據使用者過去瀏覽的歷史處理的運算。

這樣說來,如果 Continuation 能把事情簡化到最早期的程式撰寫方法,則 MVC 的概念並不是一定必要的。

2009年10月11日 星期日

Macro 的不可或缺

原本我的遊戲是以 javascript 寫成。在研讀過 PLT Scheme 的手冊後,我開始以 scheme 改寫我的遊戲軟體。 這樣做的原因主要是我欣賞 PLT scheme 中提供的 @-exp 語法。這語法類似 XML,適合用來描述遊戲的劇本,又和 scheme 完美整合。

將劇本以 @-exp 改寫後,我發現 macro 的重要性。以下是我劇本的一個片段:

@novel["家變"]{
  @room["書房"]{
    @scene["牆壁"]{
      你面對一面白色牆壁。牆壁上有條裂縫。向上直達天花板。
      @next["檢查裂縫" #:scene "裂縫"]
      @next["檢查天花板" #:scene "天花板"]
    }
    @scene["天花板"]
      天花板有點潮溼。
    }
    @scene["裂縫"]{
      裂縫中有隻螞蟻。
    }
  }
}

面對這樣的劇本,有兩種作法:
  1. novel 是 scheme function。此時,因為 room 會比 novel 早執行,因此,在執行 novel 前必須先建造一個名為 current-novel 的物件,或是使用一個 global 的物件,以存放 room 產生的資料。這使得劇本必須做小修改,而撰寫劇本的人,很可能不是一位程式設計師,必須操心這些小修改。
  2. novel 是 scheme macro。由於使用 macro,可以將建造 current-novel 的工作包括在 macro 的設計中,因此,撰寫劇本的人就不必操心這些問題。
我沒想到的是,單單劇本撰寫這樣原本以為簡單的工作,竟然也涉及到 macro 的撰寫,也因此體會了 macro 強大的能力。

在設計劇本的描述語言時,我也感受到 scheme 的 keyword 帶來的好處,以以上的劇本為例,在 next 中我使用了 #:scene 這個 keyword,它使得劇本更容易閱讀。

一個讓我驚訝的事是,我目前感受不到 PLT-Scheme 的 define-struct 的好處。原本我使用 (define-struct novel (name)) 來建立 novel 這結構,但最後我改成如同我原本使用 javascript 的作法,使用 hashtable,同時參考 SICP 的作法 來解決。