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& rdquo;？

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.4 或以上版本。请下载所属平台的安 装档；从源码编译 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 上见！