Author: Autrijus Tang

# Pugs 外典之一
Pugs 計劃概述

## 何謂 Pugs 外典？

Pugs 外典（Pugs Apocrypha）是一系列採問答體例，用以解釋 Pugs 設計及實作的文件。本外典（PA01）乃此一計劃之總要。

## 何謂 Pugs？

Pugs 始自 2005 年 2 月，是針對 Perl 6 語言進行的實作，由負責人 Autrijus Tang（唐宗漢）在開發團隊 （committers）與貢獻者（contributors）的襄助下，進行設計及開發。

## 何謂 Perl 6？

Perl 6 是 Perl 語言的下一個主要版本，由 Larry Wall 領導的團隊負責設計。Perl 是一種語境相關、多重典範之實用程式語言。 Perl 6 團隊已表示非常歡迎 Pugs 專案的誕生。

## Perl 6 規範是否已經底定？

截至 2004 年 12 月，Perl 6 大部份規格都已載明於一系列的綱要（Synopses）中。雖然綱要日後可能還會 有所更動，但目前已穩定到可以實作的地步。Larry 的啟示錄（Apocalypse）是許多綱要的基 礎。設計團隊偶爾也會發表注疏（Exegesis）， 解說啟示錄的內容。Pugs 遵循綱要之內容，當有疑義時則參考啟示錄與注疏。

## 何謂「Apocrypha」？

Apocrypha（外典）一詞源 自希臘文 απόκρυφος（隱藏），代表非正統的宗教典籍。依 希臘文，單數型應為 Apocryphon。

## 外典與 Perl 6 設計文件之關係為何？

啟示錄與綱要描述抽象的 Perl 6 語言規範；外典則與 Pugs 實作息息相關。如同 Parrot 設計文件，外典也將依據 Pugs 的狀態而不時更新。

## Pugs 會實作完整的 Perl 6 規格嗎？

會的。Pugs 將一直以最新的 Perl 6 綱要版本為實作目標。一旦有新的綱要或修訂版本出現時，Pugs 和新版不一致之處，將視為 Pugs 的瑕疵。

## Pugs 是自由軟體嗎？

是的。Pugs 採用 GPL 第二版及 Artistic License 第 2.0b5 版釋出。Artistic 2.0 最終版本一旦底定，Pugs 即會採用。

## Pugs 是否受到 Perl 基金會贊助？

沒有。在接受 Perl 基金會的三份專案補助後， Autrijus 決定捐出自己的時間，透過 Pugs 來協助 Perl 6 專案，不向 TPF 請求贊助。

## 如何取得 Pugs？

從 Subversion 或 darcs 檔案庫，可以取得最新版的 Pugs 源碼。在 CPAN 上，也會以 Perl6-Pugs 為名定期釋出。（順帶一提，若有興趣針對 Subversion 檔案庫進行離線開發，svk 也許對你會有幫助。祗用 svn 當然亦無不可。）

## 如何編譯 Pugs？

Pugs 採用標準 Makefile.PL 編譯系統；請見 README 檔案的詳細說明。由於 Pugs 是用 Haskell 語言寫成，請先安裝 Glasgow Haskell Compiler (GHC) 6.2 或以上版本。請下載所屬平台的安 裝檔；從源碼編譯 GHC 得花上不少時間。

## 何謂 Haskell？

Haskell 乃標準化的純粹函數式程式語言，具有惰性求值（lazy evaluation）特性。雖然它有許多不同的實作可用，但 Pugs 採用了 GHC 特有的若干功能，因此必須用 GHC 來編譯。

## GHC 又是什麼？

GHC 是尖端的編譯器與互動式環境，採用 BSD 式授權釋出。GHC 本身以 Haskell 寫成，能把 Haskell 編譯成位元組碼（bytecode）、C 語言程式，與某些平台的機器碼。GHC 附有完整的程式庫、為數眾多的語言延伸，以及強大的最佳化系統（藉由某 Perl 5 程式的協助）。因此，GHC 提供了解決 Perl 6 啟動問題（bootstrapping problem）的絕佳平台。

## 何謂 Perl 6 啟動問題？

Perl 6 專案的目標是自足執行（self-hosting）：Perl 6 編譯器得用 Perl 6 本身撰寫，採用 Perl 6 Rules 來剖析 Perl 6 語法，而 Rules 又是 Perl 6 語言的一部份。此外，編譯器產出之程式碼也得包含能動態執行 Perl 6 程式碼的求值器（evaluator）。要打破此種相依循環，唯有採用其它語言先實作某些部份，然後再用 Perl 6 加以重寫。

## 最初的啟動計劃為何？

根據 Parrot 答客問，最初的計劃是利用 Perl 5 進行啟動：先擴充 Perl 5，使其執行於 Parrot 虛擬機器上（透過 B::Parrot 或 Ponie），再以 Perl 5 實作 Perl 6 編譯器，最後透過 p5-to-p6 轉換器將編譯器轉譯成 Perl 6。不過，雖然 Perl6::Rules 確實在 Perl 5 上實作了 Rules 的雛型，但對於建構編譯器而言仍顯得不夠成熟。因此，啟動計劃轉而以 C 語言代替。

## 修訂後的啟動計劃為何？

根據一份 2005 初的建議 書，首先應採用 C 語言實作 Rules 引擎（即為 PGE）， 用它將 Perl 6 剖析成 Parrot 的抽象語法樹（AST）， 接著在 Parrot 裡實作 AST 求值器。Ponie 和 p5-to-p6 仍在進行中，但已非啟動程序中的關鍵成份。

## Pugs 能如何協助 Perl 6 啟動？

在啟動程序中，常存在許多瓶頸，使得許多依賴這些瓶頸的工作無法推展。好比說，沒有可用的 Perl 6 實作，就難以為 Perl 6 撰寫單元測試與標準程式庫；在缺少 AST 介面的情況下，也沒辦法撰寫 AST 求值器。Pugs 為此程序的各層面提供可用的替代元件，因此解決了上述的困境。

## Pugs 有助於 Perl 6 語言設計嗎？

在缺少可用的實作時，很難看出規格內的不一致與例外狀況。然而，假如在實作許久之後，纔發現設計上的瑕疵，可能就得在重新架構上耗費許多心力。藉由 提供可用的 Perl 6 實作，Pugs 可做為先期的確認平台；這樣不但能趁早解決問題，也可以鼓勵更多人運用 Perl 6 的特性。

## 為何選擇 Haskell？

Haskell 具有許多與 Perl 6 特點相應的功能：Perl 6 Rules 與 Parsec 十分相似；兩種語言裡都有惰性串列求值；延續函式（continuation）則可利用 ContT 單子轉換器（monad transformer）來建構。這讓雛型開發工作簡化許多：首支可用的直譯器只花了一星期便釋出了，在第三個星期時，我們已經有了可 供單元測試的全功能 Test.pm 模組。

## Pugs 是編譯器還是直譯器？

和 Perl 5 相似，Pugs 先把 Perl 6 程式編譯成 AST，然後再用內建的求值器加以執行。不過，未來 Pugs 可能會提供支援多種編譯器後端的編譯器介面。

## 考慮納入哪些編譯器後端呢？

如果要實作編譯器的話，首先很可能會是產出 Perl 6 程式碼，類似 B::Deparse 模組的編譯器後端。接下來則可能產出 Haskell 程式碼，並交由 GHC 編譯成 C 語言。屆時，下一個目標很可能是 Parrot AST 介面。如果有人願意協助的話，我們也可能再加入其它後端（譬如 Perl 5 bytecode）。

## 預定的 Pugs 開發計劃為何？

Pugs 之主要/次要版本號將逼近 2*π；次版本號中的各小數位皆代表一項里程碑。版本號的第三位數會在每次釋出時遞增。目前的里程碑 為：

- 6.0: 首次釋出
- 6.2: 基本輸出入與流程控制元件、可覆寫變數（mutable variables）與賦值（assignment）。
- 6.28: 類別（classes）與特質（traits）。
- 6.283: 規則（rules）與文法（grammars）。
- 6.2831: 角色組合（role composition）及其它執行時期功能。
- 6.28318: 巨集（macros）。
- 6.283185: 如有必要，將 Pugs 移植至 Perl 6。

## Pugs 的可攜性如何？

Pugs 可在 Win32、Linux 與多種 Unix 系統上執行。GHC 的移植者名單與下載網頁有詳細的資訊。從 6.2.0 開始，Pugs 團隊也會提供若干平台的安裝檔。

## Pugs 的速度是否夠快？

在 Parsec 的強力支援下，Pugs 的解譯器很快。不過 Pugs 的求值器目前尚未最佳化：在一般 PC 上每秒約處理 1000 個運算符，大約比 Perl 5 慢上 100 倍。這對實現雛型語言功能來說，已經夠快了；假如還不能滿足你的需要，請考慮幫忙開發編譯器後端。

## 有 Perl 6 模組的 CPAN 嗎？

沒有。當前發佈 Perl 6/Pugs 模組較好的方式，是交由 openfoundry.org 的提交者，將你的模組放到 Pugs 原始碼檔案庫下的 modules/ 目錄。最好能同時提供該模組的測試案例，讓我們對該模組多些了解。

但情況也不是就那麼糟。假如你夠耐心，可以等候 Pugs::MakeMaker 和 Module::Install::Pugs 的出現。等到以上模組出現在 CPAN 上，表示我們已經解決了散佈上的問題。你就可以開始把東西丟上 CPAN 了。當然，隨時歡迎各方提供其它意見。

## Pugs 能與 Perl 5 程式庫共用嗎？

雖然目前還不行，但我們未來可能會照 Autrijus 之前實作 Inline::MzScheme 的方式，撰寫 Inline::GHC 模組，讓 Perl 5 與 Haskell 模組能相互溝通。如果成功的話，架一個 Inline::Pugs 在上面也非難事。不然，我們也可能寫個產出 Pugs AST 碼的 Perl 5 程式碼解譯器，讓 Pugs 能執行純以 Perl 寫成的模組。再不然，也可以把 Pugs AST 編成 Perl 5 的 AST，不過這更是純屬臆測。

## Pugs 能與 Haskell 程式庫共用嗎？

目前你可以把 Haskell 程式庫靜態鏈接至 Pugs 的內建函式，祗需修改 Prim.hs 內的幾列程式碼即 可。我們正考慮撰寫 hs-plugins 的簡易界面，讓 Pugs 能動態載入 Hasekll 程式庫，甚至在 Perl 6 中內嵌 Haskell 程式碼。

## Pugs 能與 C 程式庫共用嗎？

還不行。不過 HaskellDirect 配上前述的 hs-plugins，似乎會是與 C、CORBA 及 COM 程式庫溝通的簡單方式。

## 我會 Perl 5，不懂 Haskell。我能幫 Pugs 的忙嗎？

當然！Pugs 的標準程式庫與單元測試都是以 Perl 6 寫成的，而我們總是需要更多的測試和程式庫。這方面的工作只需要懂 Perl 5，再花上幾分鐘熟悉少部份語法的不同之處即可。當然，過程中你也可能會學到一些 Haskell 相關的知識。

## 我會 Haskell，但不懂 Perl 5。我可以幫忙嗎？

當然！Perl 6 和 Haskell 有很多相似之處，好比說依據型別分派的函式（type-based function dispatch）、以函式為值（first class functions），以及局部套用函式（currying）等等；因此，要了解語法也會簡單許多。總是有許多功能的待辦測試等著實作，不用怕找不到事情 做。

## 我會一點 Perl 6。我能用 Pugs 做什麼？

先看看 examples/ 目錄裡的範例程式。已經有人用 Pugs 寫了網站應用軟體與報表系統。假若你發現 Pugs 有不足之處，請告訴我們，以便實作。

## 哪裡可以學 Haskell？

Haskell 首頁和 Wiki 會是不錯的開始。有許多線上教學文件可看；Yet Another Haskell Tutorial 可能是其中最容易上手的。由於 Pugs 中大量應用單子轉換器 （monad transformer），建議讀讀 All About Monads。書的話，Algorithms: A Functional Programming Approach、Haskell: The Craft of Functional Programming 和 The Haskell School of Expression 都是很好的入門讀物。此外，freenode 的 #haskell 頻道上有許多熱愛 Haskell 的人可以幫忙。

## 哪裡學得到 Perl 6？

Perl 6 首頁有許多線上文件。每隔一兩個星期，Perl.com 上會有新的 Perl 6 通信論壇摘要，想趕上 Perl 6 的開發進度者一定不能錯過。在書藉方面，Perl 6 and Parrot Essentials 和 Perl 6 Now 都很有幫助。

## 要如何學習實作程式語言？

Types and Programming Languages 一定要讀。Pugs 最初是 Autrijus 在自學此書時的習作；它在實作期間也一直是重要的指南。它的續集 Advanced Topics in Types and Programming Languages 同樣十分重要。熟悉其它多重典範語言（如 Mozart/Oz、Curry 、O’Caml 等）可能也有幫助。此外，GHC commentary 為 GHC 實作提供了詳實的描述。

## 我想幫忙，該怎麼做？

首先，發一封空白信到 perl6-compiler-subscribe@perl.org， 訂閱 perl6-compiler 通信論壇。接著加入 irc.freenode.net 的 #perl6 IRC 頻道，看看有什麼待辦事項；不妨與 #perl6 上的 Pugs 團隊連繫，以加入開發團隊。咱們 IRC 上見！