2007 資訊營 Python 程式語言課資料頁
2006 資訊營程式語言課資料頁

2007 資訊營 Python 程式語言課資料頁

CSCamp 2007 Python Programming Language Data

By Shu-Chun Weng, 翁書鈞

投影片

Microsoft Powerpoint .ppt 檔

講義

Microsoft Word .doc 檔


2006 資訊營程式語言課資料頁

CSCamp 2006 Programming Language Data

By Shu-Chun Weng, 翁書鈞

簡介

Programming Language 是計算機科學的語言學,如同外文系的語言學, PL 目的在 比較各種語言的差異、追溯語言發展、歸納語言的共同點與觀察語言的使用。另外 還包括了開發語言功能 (Language feature)、證明編譯器 (compiler) 正確性甚至 開發新語言。

這門課將展示大量不同程式語言並稍微簡介各語言特色和用途。接著介紹各種形態 的語言開發環境。然後著重於當前最多語言使用的編譯模式介紹編譯的結構。若時 間允許可以談到 type theory 的出現與用途。

投影片

Microsoft Powerpoint .ppt 檔

講義

Microsoft Word .doc 檔

程式語言的產生

最初的電腦並不是「Programmable」的。在真空管的時代所謂的「寫程式」是去排 列真空管的位子、把要接的接腳用電線接起來,然後把電源打開看著真空管一根根 亮起來,慢慢把結果算出來。當時除了程式要寫對,甚至還要考慮到一個真空管不 要亮太久免得燒掉!

之後出現了可以在電腦開著的時候輸入程式再執行的「Programmable」電腦。而輸 入程式的方法則五花八門:按鈕(真的有系上教授說他用過!)、打卡到現在的打 字。到了這個時候當然就要考慮到輸入程式的難易囉!於是程式語言就誕生了。

電腦裡最基本的資料、程式表示法當然是機械碼,無論用一跟零或用十六進制表示 都如天書。最早的程式當然非用機械碼寫不可,可是會寫的人也不多。於是之後就 出現了組合語言。組語跟機械碼幾乎是一一對應,唯一的好處是比較好看、比較好寫。

日常生活中所謂的程式語言則是高階語言。相對於比較低階的組語和機械碼,高階 語言以「有辦法讓人寫」為目標,要執行的時候再轉換成機械碼。越到後來程式越 寫越大,一個普通的程式常常幾百、一千行,筆者日前才剛完成一個五千行的 project 。若是完整的應用程式或者完整的作業系統則更誇張(PTT BBS全站,包括維持運 作的工具約六萬行;Linux kernel 不含 runtime library 共四百萬行)。這時候 只是易看易寫已然不足,方便開發、方便除錯、方便多人合作、可以驗證正確性等 需求開始出現,也使 Programming Language 這門 Computer Science 的分支活躍起來。

語言比較觀點

  1. 可移植性:同樣的程式可不可以在不同的作業系統、不同的 CPU、Architecture 上使用?在切換環境的時候原程式要修改的幅度有多大?是執行檔完全不用改變、只 要重新編譯、要修改參數編譯、要修改原程式或是要完全重寫?
  2. 語言結構性:從無結構,執行順序可以跳來跳去,到結構化只允許特定控制指令 (control statement)、函式導向、物件導向都關係到程式開發難易以及維護難易。
  3. 語言可讀性:雖然程式語言是為了方便電腦處理而發展出來,但它更伴演了人與 電腦溝通的界面。可讀性許多時候是掌握在寫程式的人手中,但語言本身是否提供一 些方便的功能也影響寫出來的程式是否好讀。
  4. 語言實用性:一個語言被設計出來通常有他的特殊需求或目的。可能是效率特別 重要,可能重視彈性,可能以控制控制使用者介面 (UI) 為主。這些設計選擇都影響 了實用性和可用範圍。
  5. 程式執行方式:大制上分成直譯 (Interpret),編譯 (Compile), 或虛擬機器 (Compile to byte code)。直譯式語言由直譯器邊讀程式就邊執行,通常效率較差但 可以邊寫邊除錯;編譯式語言則要寫好後透過編譯器編譯成可執行檔之後執行,效率 較好相對的也比較難找錯;用虛擬機器的語言則是編譯式語言的特例,編譯出來後並 不是可執行檔而是虛擬機器的指令,要執行時由虛擬機器讀取執行,好處是只要有虛 擬機器的系統就可以用那份「執行檔」,不用重新編譯。

常見語言分類

低階語言

泛指機械碼及組合語言,可以觸碰到電腦最低階的部份、可以完全控制電腦、發揮 全部功能。另一方面則因為跟電腦太相關,完全不具可移植性,如果想要移殖 (porting) 原有的功能到別的環境幾乎一定要完全重寫。

同時為了電腦容易讀取與解讀,低階語言的設計完全沒有結構性可言。寫起程式充滿 彈性,但可讀性也非常低。而且因為每個指令的功能單純,寫出的程式非常長。

高階非結構化程式語言

這種程式語言寫起來和低階語言最大的差別就是比較像人做事的方法。首先有了「變數 」,不用自己控制記憶體和暫存器 (register);然後有控制語句像「if」、「while」 等判斷、重複執行的功能。另外一大差別則是因為它們夠「高階」,和系統、環境的緊 密性低,移執時大都只要重新編譯或做些許修改即可。

但寫程式的人仍然主要用「goto」做為控制執行順序的方法,恣意在程式中跳躍,因此 稱為「非結構化程式」。常見的例子如 COBOL, Fortran, QuickBasic 等。

結構化程式語言 (Structured)、函式導向程式語言 (Procedure-Oriented)

顧名思義,就是相對於非結構化程式語言,不再允許在程式中任意跳來跳去,一定要用 語言提供的控制結構。這些限制事實上不但不會使程式比較難寫,而且因為控制結構單 純還比較好理解、比較不容易出錯。另一方面因為編譯器完全知道可能的程式走向也可 以產生比較有效率的組合語言。

同時支援函式,可以將同樣的工作抽離出來、避免重複。而遞迴 (recursion) 也讓許 多演算法的實作簡單化。如快速排序法 (quick sort) 要在沒有遞迴的程式語言上實作 要自己做許多工作。

現在最常見的一些語言大致上都可以歸類在這種或它的加強版當中。如 Pascal, Perl, VB 等等。C 語言雖然提供了 goto 語法,但是顯少有人用到,因此也可以歸在其中 (事實上有些人稱 C 語言為「中階語言」,因為它對電腦的控制力與組合語言幾乎無分 軒輊。)

物件導向程式語言 (Object-Oriented)

這類語言比函式導向更進一步,不只將工作抽離出來,更將資料抽出來,並把「處理資 料」的工作放在靠近儲存資料的地方。增加模組化和除錯效率。現在最常見到的工業用 程式語言幾乎都屬於這類,如 C++, Java, C#, VB.NET 等。也有不少其他比較非主流 的如 ruby 或 python 也支援物件導向。

腳本程式語言 (Scripting Language)

如同名字所示,大多用在處理資料、寫「腳本」用的語言。同時大部份是直譯語言。最 常見的是 shell script 和 Perl (Perl 事實上是編譯語言,可是以直譯的外表運作)。 另外 ruby, python 事實上也都是 scripting language。

函數式程式語言 (Functional Language)

這類與上面的語言有相當大的差異。前面所說的都是以「描述動作」為目標,functional language 則以「描述結果」為目標,一切東西都是數學上的函數,只需要參數輸入及返 回值輸出。而寫這類程式就是以手邊有的函數加上一些自己定義的行為來組合出要的結果。

常見的例子有 lisp, scheme (lisp 的一種方言), Camel, Haskell 等等。其中 lisp 以彈性極大稱著,最受人工智慧研究者青睞。而 Haskell 有許多 type system 上的先進 功能,在 Programming Language 學界是超級大熱門。Camel 則種進化版 OCamel ,是加 上 Object-oriented 的 functional language!

邏輯程式語言 (Logic Programming Language)

這又是另一類想法完全不同的語言。這次要描述的是「當 A 為真時,B 為真」的關係。 之後給定已知,由電腦推算出所求是否為真以及還有哪些可能的設定會讓所求為真。事實 上見的到的幾乎也只有 Prolog 一種語言,因為其自動推論的特性也常為人工智慧學者所用。

網頁腳本程式語言

內嵌在 HTML 網頁中,由瀏覽器執行控制網頁的顯示。常見的是 javascript (ECMAscript) 和 VBscript。

伺服器端腳本 (Server Pages)

是開發網頁時在伺服器端所寫的程式,以之根據後端資料庫、登入狀況等資訊產生網頁給 使用者,並處理使用者的回應。最常見的有 php, asp 和 jsp 三種,都是內嵌在 HTML 檔案裡。

硬體描述語言 (Hardware Description Language)

這種語言不是用來寫程式,而是用來設計硬體電路的,可以從名字中沒有「Programming」 的字樣看出來。雖然有著和其他程式語言類似的語法,但是因為根本上是用來描述電路連 接,因此撰寫方式也和普通程式語言相當不同。常見的是語法像 Pascal 的 VHDL 和像 C 的 Verilog。

其他程式語言

Forth 是種相當有趣的語言,整個世界由兩個堆疊 (stack) 和一個字典構成,經過定義 函式、操作堆疊甚至可以自行定義語法!就連 Object-oriented 的語法都可以輕鬆建立 起來,是種獨外於其他程式語言的有趣設計。

還有一類「秘術程式語言」(Esoteric Programming Language) 並不是真的設計來寫程式 的。像 Whitespace 語言只用空白鍵、tab和換行等空白字元來寫程式;Befunge、Argh! 則是視覺化的:在視覺上的二維平面移動、運算;Brainfuck 只用特殊符號。

型別系統 (Type System)

在最低階的語言中資料只以 byte 數做分別,到了高階一點的語言開始會分整數、字元、 浮點數、雙倍精確度符點數等型別。物件導向程式語言中使用者自行定義的型別佔了相當 重要的地位,同時還有型別的順序關係。在函數式程式語言中因為函數也可以做為傳回 值,因此有更高階的型別。

在早期語言中關於型別比較精細的檢查通常留到執行期做,除了效率較差也讓開發者無法 提早知道程式是否有錯。因此越後來的語言越重視在編譯期可以檢查到多細,目標是保證 經由這些檢查後,在執行期絕對不會發生給的物件的型別和預期不同,同時也希望可以限 制越少越好。

程式分析 (Program Analysis)

這也是期望在編譯時做更多的檢查:如是否可能寫入一個還沒開啟或已經關閉的檔案, 是否可能給使用者高於他應有的權限,是否可能被駭客 ("racker", not "hacker") 取得過多資訊甚至做他不該做的事。

這些檢查有些非得在執行時動手腳不可,有些則可以在編譯時給予錯誤或警告訊息。 程式分析就是研究如何以最高效率加入執行期檢查,以及如何做出最適當的警告、 該拒絕哪些危險行為。 (警告並不是越多越好,因為太多的警告只會使使用者放棄 修正而漏掉其中真正的危險)