最近更新: 2007-06-25

如何區分動態語言和靜態語言

雖然我們總是說著動態語言(dynamic language)、靜態語言(static language),但區分方式並不是語法,而是運行環境。

如果程式影像在載入前便確立並儲存,那麼是靜態語言[If the image of program which including op code and data is static in disk before loaded, we call it 'static language'.]。這句話對學過作業系統概論或組合語言的人比較容易理解。因為在組合語言中,要求程序員設置 code 節區, data 節區等內容載入記憶體的位置。所以我們很容易聯想記憶體中的程式影像儲存在檔案系統中的情形。與之相對的是,若程式影像在載入後才建立,則是動態語言。

在靜態語言中,軟體公司透過編譯動作(compile),事先建立程式影像並儲存在磁碟中。如此一來,便可以簡化使用者系統的載入器(loader)設計,甚至內建在作業系統之中。進而有效降低載入器和作業系統的磁碟空間需求。嗯,這些內容聽在現在的資訊科系學生耳中,想必是無法理解。一套 Windows 就要 1GB 磁碟空間,什麼載入器要簡化云云,簡直不可思議。但我玩過記憶體 640K 、磁碟空間 1.2MB 的 DOS 環境,還在這環境中用組合語言寫過程式。所以我親身體驗過那種以 KB 為單位在計較的情形。

另一方面,動態語言還有一個特點,即「互動式程式設計(interactive programming)」。動態語言程式的載入器都包含了語法解析的能力,所以很複雜且龐大,我們一般直接稱為解譯器(Interpreter)。在載入程式碼之後,依然可以接受使用者輸入程式碼。當其接受程式碼後,便立即解譯並改變程式影像之內容。

我玩過解譯式 BASIC (PC BASIC, GW BASIC) 以及編譯式 BASIC (QuickBASIC) 。我也玩過 C 語言解譯器,可以線上 coding 及運作。那時說編譯、解譯,很少說什麼動態語言、靜態語言。一種程式語言固定一種運行方式,涇渭分明的情形,大約是近10年才形成的吧 (就是 Java 與 Perl 嶄露頭角時)。

我的說法是老派程序員的觀點。也許現在的程序員另有一套說法吧。

相關文章
樂多舊網址: http://blog.roodo.com/rocksaying/archives/3530367.html

樂多舊回應
jxvenus@263.net(jxvenus) (#comment-21917445)
Tue, 16 Aug 2011 00:03:29 +0800
按这样区分,objective-c是静态语言? 可一般说来,它的某些特征很动态。。。
未留名 (#comment-21918415)
Tue, 16 Aug 2011 17:37:22 +0800
不只 objective-c ,就連 C + glibc 或是 C++ 的 RTTI,都帶入了你所說的「動態」。
它們設計了一套型態解析與配置的子系統,同時在編譯時,將大量的型態資訊保留在資料節區中。
如此一來,當程式運行時,它就可以透過型態子系統與資料節區中的大量型態資訊,在執行時期解析型態。

一套型態子系統如果再配上一套新的語法解析器,就是一個新的程式語言囉。

事實上,按照我這種老式觀點來看現在的程式語言,動態語言與靜態語言之間的區別其實非常模糊。
差異化的主因,是compiler/interpreter的設計複雜度,以及程式語言設計者的設計哲學。

不過 compiler 的設計複雜度總是比較高,因此限制就比較多。
所以用 compile 這個動作為區分點,我個人認為還是很管用的。