文學編程
![本頁使用了標題或全文手工轉換](http://upload.wikimedia.org/wikipedia/commons/thumb/c/cd/Zh_conversion_icon_m.svg/35px-Zh_conversion_icon_m.svg.png)
![]() | 此條目需要精通或熟悉計算機科學的編者參與及協助編輯。 |
此條目目前正依照其他維基百科上的內容進行翻譯。 (2022年8月4日) |
文學式編程(英語:literate programming)是由高德納提出的編程方法,希望能用來取代結構化編程范型。[1]
正如高德納所構想的那樣,文學編程范型不同於傳統的由計算機強加的編寫程序的方式和順序,而代之以讓程序員用他們自己思維內在的邏輯和流程所要求的順序開發程序。[2]文學編程自由地表達邏輯,而且它用人類日常使用的語言寫出來,就好像一篇文章一樣,文章里包括用來隱藏抽象的巨集和傳統的源代碼。文學編程工具用來從文學源文件中獲得兩種表達方式,一種用於計算機進一步的編譯和執行,稱作「繞出」(tangled)的代碼,一種用于格式化文檔,稱作從文學源代碼中「織出」(woven)。[3]。雖然第一代文學編程工具特定於計算機語言,但後來的工具可以不依賴具體語言,並且存在於比編程語言更高的層次中。
概念
[編輯]文學程序是用自然語言(比如英語)寫出來的對程序邏輯的解釋,程序中交織點綴着巨集和傳統源代碼段。在文學編程的源文件中,巨集很簡單,它或與標題類似,或是解決編程問題時用人類語言描述抽象的解釋性短語。它把代碼段或更低層次的巨集隱藏了起來,且與計算機科學教學時經常用到的,用虛擬碼寫的算法相似。這些任意解釋的短語成為新的精確的操作符,操作符由程序員在運行過程中創建,組成了在基本編程語言之上的「元語言」。 預處理器用於替換任意層級,說得更準確些是「在'網'和巨集之間建立聯繫」[4],用命令"tangle"產生可編譯源代碼,用命令"weave"產生文檔。預處理器還提供了寫出巨集的內容的能力和在文學程序源文件中的任何地方增加已創建的巨集的能力,由此不必受傳統編程語言強加的那些限制或是打斷自己的思路。
優點
[編輯]根據高德納本人所說[5][6],文學編程為高質量程序而生,因為它強迫程序員顯式描述程序背後的思路,讓不充分的設計決策無所遁形。高德納還聲稱文學編程提供了一流的文檔系統,它並非插件,而是隨着編程思路的慢慢展現而不斷自然發展的過程[7]。產生出來的文檔使作者能在以後的任何時間重新找到自己的思路,也能使其他程序員更容易理解程序的建構過程。這與傳統文檔不同,那裡程序員必須和編譯器規定的代碼順序寫在一起,還必須從代碼和注釋中重現當時的思路。文學編程的元語言能力也據稱[誰?]普遍利於思考,能從更高的層次統觀代碼,也能增加人的智能可成功保持和處理的概念數量。該概念適用於大規模編程,商業級程序的適用性被 TeX 代碼版本證明為文學程序。
誤解
[編輯]文學編程常常被誤解[8]為不過是從有源代碼和注釋的文件中產生格式化文檔,或是在代碼里寫大量的注釋。這一誤解導致那些文檔析出工具,如Perl的Plain Old Documentation系統也被稱為「文學編程工具」。儘管如此,因為這些工具沒有實現隱藏在自然語言巨集系統背後的「抽象概念網」,或是提供把機器規定的源代碼順序變為人類思維更容易理解的順序的能力,它們不能在高德納提出的意義下被稱作文學編程工具。[8][9]
例子
[編輯]一個文學編程的經典例子是標準Unix單詞計數程序wc
的文學實現。高德納在他的《文學編程》書中的第12章展示了這個例子的CWEB版本。後來它也為Noweb文學編程工具而重寫。[10]這一例子漂亮地闡釋了文學編程的基本元素。
- 創建巨集
下面這個wc
的文學編程[10]代碼片斷展示了在文學編程中用來創建巨集的自然語言的描述性詞組有多隨意,巨集作為文學編程語言中新的「操作符」,並且隱藏了代碼塊或其它的巨集。由兩個尖括號組成("<<...>>
")的標記符號表示巨集,"@
"符號在noweb文件中表示一節代碼的結束。"<<*>>
"符號表示「根」,即最上層節點,文學編程工具要從這裡展開巨集組成的網。實際上,擴展的源代碼可通過任何節和小節(即標為"<<代码块名>>=
"的代碼)寫出來,所以一個文學程序文件可包括多個機器源代碼文件。
wc的目的是對多個文件中的行、單詞和字母計數。文件中的行數是......../更多解釋/
这里是由noweb程序wc.nw定义的文件wc.c的概述:
<<*>>=
<<包含头文件>>
<<定义>>
<<全局变量>>
<<函数>>
<<主程序>>
@
我们必须包含标准输入输出定义,因为我们想发送格式化的输出到stdout和stderr上。
<<包含头文件>>=
#include <stdio.h>
@
還要注意,塊的分解可以在文字程序文本文件的任何地方進行,不一定按照它們在封閉塊中的順序,而是按照包含整個的解釋性文本中反映的邏輯的要求 程序。
- 作為網的程序 - 巨集不只是節的名字
巨集和標準文檔中的「節名」不同。文學編程的巨集能隱藏任何代碼塊,並且被用於任何低層次的機器語言操作符內,常常在如"if
", "while
"或 "case
"這樣的邏輯操作符內。這會在下面這段文學程序wc
的代碼片斷中解釋。[10]
这里的代码块做了计数的工作,这正是wc存在的目的,实际上非常容易写。我们察看每一个字母并且如果它是一个单词的开始或结束,则会更改状态。
<<扫描文件>>=
while (1) {
<<Fill buffer if it is empty; break at end of file>>
c = *ptr++;
if (c > ' ' && c < 0177) {
/* visible ASCII codes */
if (!in_word) {
word_count++;
in_word = 1;
}
continue;
}
if (c == '\n') line_count++;
else if (c != ' ' && c != '\t') continue;
in_word = 0;
/* c is newline, space, or tab */
}
@
實際上,巨集能代表任意的代碼塊和其它巨集,並且因此比自頂向下或自底向上的代碼塊或小節更通用。高德納說當他意識到這一點後,他開始把程序想成不同部分組成的「網」。[1]
- 人的邏輯順序,而不是編譯器的
在noweb文學程序中,除了可以任意順序展現代碼外,巨集背後的代碼塊,一旦由"<<...>>=
"引入,可以在文件後面的任何一個地方通過簡單地寫"<<代码块名>>=
"進行擴充並且往裡添加更多的內容,如下面這個代碼片斷所示("+"為了可讀性而被文檔格式化器所添加,它並不在代碼中)。[10]
The grand totals must be initialized to zero at the beginning of the program.
If we made these variables local to main, we would have to do this initialization
explicitly; however, C globals are automatically zeroed. (Or rather,``statically
zeroed.'' (Get it?)
<<Global variables>>+=
long tot_word_count, tot_line_count,
tot_char_count;
/* total number of words, lines, chars */
@
- 記錄思想碰撞的火花,創建出類拔萃的文檔
文學編程的文檔作為寫程序的一部分而產生。替代注釋作為源代碼的附註提供,文學編程包含每一層概念的解釋,將較低級別的概念推遲到適當的位置,允許了更好的想法交流。 上面文字 wc
的片段顯示了程序及其源代碼的解釋是如何交織在一起的。 這種思想的闡述創造了像文學作品一樣的思想流動。Knuth 著名地寫了一本「小說」,解釋了計算機策略遊戲巨洞冒險的代碼,完全可讀。[11]
文學編程工具
[編輯]第一個發布的文學編程環境是WEB,由高德納於1981年為他的TeX排版系統而引入。它使用Pascal作為其基礎編程語言,使用TeX作為文檔排版工具。完整的帶注釋的 TeX 源代碼在高德納的5卷計算機與排版中的TeX: The program里被發表。早在1979年,高德納私下使用過一個名叫DOC的文學編程系統。他受到皮埃爾•阿諾德•瑪尼夫思想的啟發。[12]. 免費的 CWEB, 被高德納和 Silvio Levy編寫,是適用於C 和 C++的WEB, 在大部分操作系統上運行,並可以產生TeX和PDF文件.
其它的文學編程概念的實現有noweb和FunnelWeb,它們都是源代碼獨立的。Noweb以其簡單而知名:只有2個文本標記約定和2個調用被需要以使用它,它也允許HTML文本格式化而不是通過TeX系統。FunnelWeb是另一個不依賴於TeX的程序,可以輸出HTML文檔。它有更複雜的標記(「@」轉義任何 FunnelWeb 命令),但有更多彈性選項。
Leo 文本編輯器是一個大綱編輯器,支持可選的 noweb 和 CWEB 標記。 Leo 的作者混合了兩種不同的方法:首先,Leo 是一個大綱編輯器,有助於管理大文本; 其次,Leo 融合了一些文學編程的思想,其純粹的形式(即 Knuth Web 工具或「noweb」之類的工具使用它的方式)只有在一定程度的創造性和使用編輯器的情況下才有可能 以作者未完全設想的方式(在修改後的 @root 節點中)。 但是,這個和其他擴展(@file 節點)使大綱編程和文本管理成功且容易,並且在某些方面類似於文學編程。[13]
Haskell編程語言對半文學編程有原生支持,其來源於CWEB但用了較簡單的實現。如果想要TeX輸出,你可以寫一個樸素的LaTeX文件,一個給定的環境標記出源代碼; LaTeX可以被設置處理那個環境,Haskell 編譯器查找正確的標記來確定編譯的Haskell語句,像是注釋一樣捨棄掉TeX文檔。但是,像以上描述,這不是高德納文學編程的本意。Haskell的函數式,模塊化[14] 使得語言中直接文學編程更加簡單,但它遠不如「繞出」可以以任意方式重組的 WEB 工具之一強大。
參見
[編輯]- Sweave - an example of use of the "noweb"-like Literate Programming tool inside the R language for creation of dynamic statistical reports
參考文獻
[編輯]- ^ 1.0 1.1 v w x y z Knuth, Donald E. Literate Programming (PDF). The Computer Journal (British Computer Society). 1984, 27 (2): 97–111 [January 4, 2009]. doi:10.1093/comjnl/27.2.97. (原始內容 (PDF)存檔於2019-08-19).
- ^
"我感覺自頂向下和自底向上是兩種截然相反的方法論:一個更適合分析程序,一個更適合創建程序。但是,使用WEB編程後,我意識到不必在自頂向下和自底向上之間艱難抉擇,因為我們最好把程序的結構看作網狀而不是樹狀的。層級結構是存在的,但對於程序來說,最重要的是其結構的關係。一個複雜的軟件由多個簡單部分和它們之間的簡單關係構成。程序員的任務是用人類最易理解的順序,而不是用像自頂向下或自頂向上之類刻板僵硬的順序,來描述清楚這些部分和關係。"
- ^ 如果有人記得該工具的第一個版本稱作WEB,一段好玩的高德納隱藏其中的文學作品引用不言自明:「啊,自從我們第一次撒謊,就開始編織(weave)一張錯綜複雜(tangled)的網」 - 沃爾特·司各特, in Canto VI, Stanza 17 of Marmion (1808) 寫於1513年的一部關於弗洛登戰役的史詩。-- 該引文實際上出自1986年5月喬恩·本特利和高德納發表在"Communications of the ACM, vol 29 num 5 on p.365"的經典欄目「編程珠璣」上的一篇文章的引言中
- ^
"WEB的巨集至多允許帶一個參數。同樣地,我這麼做是出於簡單考慮,因為我注意到大多數帶多參數的應用其實可歸納為單參數的情況。比如說,假如你想定義某個東西……換言之,一個巨集的名字可以作為另一個巨集的參數,這是很有用的。這個特殊的技巧使其成為可能……"
- ^ Knuth, Donald E.; Andrew Binstock. Interview with Donald Knuth. April 25, 2008 [January 4, 2009]. (原始內容存檔於2021-02-23).
然而對我來說,文學編程確實是由TeX項目衍生出來的最重要的東西。它不僅讓我前所未有地更快地寫和維護可靠性更高的程序,而且成為我自20世紀80年代以來的最大的快樂之源——它有時實際上是不可或缺的。我做的其它一些大程序,比如MMIX元模擬器,用我見過的任何一種其它的方法論是無法寫出來的。其複雜性讓我有限的智能望而卻步。沒有文學編程,我的整個事業規劃就會轟然倒塌。……文學編程是你更上一層樓的必要工具。
- ^
"我使用WEB時學到的另一令人驚奇的事情是傳統編程語言導致我寫出了低劣的程序,儘管我還沒意識到我在做什麼。我原來的想法是WEB僅作為寫文檔的工具,但我後來發現用WEB寫的程序比我用其它語言寫的程序都要優秀。"
- ^
"因此WEB語言允許人們用"意識流"順序表達程序。TANGLE is able to scramble everything up into the arrangement that a PASCAL compiler demands. This feature of WEB is perhaps its greatest asset; it makes a WEB-written program much more readable than the same program written purely in PASCAL, even if the latter program is well commented. And the fact that there's no need to be hung up on the question of top-down versus bottom-up, since a programmer can now view a large program as a web, to be explored in a psychologically correct order is perhaps the greatest lesson I have learned from my recent experiences."
- ^ 8.0 8.1 Dominus, Mark-Jason. POD is not Literate Programming. Perl.com. March 20, 2000 [January 3, 2009]. (原始內容存檔於2009-01-02).
- ^
"我選擇WEB作為名字,部分因為它是英語中很少的幾個沒有用於計算機的三字詞語之一。但隨着時間流逝,我越來越喜愛這個名字,因為我認為最好把一個複雜的軟件確確實實地看成由簡單材料以精巧的方式拼出來的一張網。我們通過理解複雜系統的各個簡單部分和這些部分與其直接鄰居的簡單關係來理解複雜系統本身。如果我們用網的概念來表達程序,我們就能用一種自然且圓滿地方式強調其結構上的屬性。"
- ^ 10.0 10.1 10.2 10.3 Ramsey, Norman. An Example of noweb. May 13, 2008 [January 4, 2009]. (原始內容存檔於2021-02-23).
- ^ The game, also known as ADVENT, was originally written by Crowther in about 700 lines of FORTRAN code; Knuth recast it into the WEB idiom. It is available at literateprogramming.com (頁面存檔備份,存於網際網路檔案館) or on Knuth's website 網際網路檔案館的存檔,存檔日期2008-08-20..
- ^ de Marneffe, Pierre Arnoul. Holon Programming - Report PMAR 73-23. University de Liège, Service d'Informatique. December 1973.
- ^ Ream, Edward K. Leo's Home Page. September 2, 2008 [January 4, 2009]. (原始內容存檔於2006-01-28).
- ^ Hughes, John. Why Functional Programming Matters (PDF). Institutionen för Datavetenskap, Chalmers Tekniska Högskola,. January 9, 2002 [January 4, 2009]. (原始內容存檔 (PDF)於2009-07-11).
延伸閱讀
[編輯]- Knuth, Donald E. Literate Programming. Stanford, California: Stanford University Center for the Study of Language and Information. 1992. ISBN 978-0937073803.
- Guari, Eitan M. TeX & LaTeX: Drawing and Literate Programming. McGraw Hill. 1994. ISBN 0-07-911616-7. (includes software).
- Nørmark, Kurt. Literate Programming - Issues and Problems. University of Aalborg. August 13, 1998 [2010-01-03]. (原始內容存檔於2011-08-13).
外部連結
[編輯]- literateprogamming.com (頁面存檔備份,存於網際網路檔案館)
- comp.programming.literate FAQ (頁面存檔備份,存於網際網路檔案館) at Internet FAQ Archives
- Literate Programming newsgroup
- LiteratePrograms (頁面存檔備份,存於網際網路檔案館) a literate programming wiki.
- Select (頁面存檔備份,存於網際網路檔案館) A literate programming example using noweb
- Softpanorama page (頁面存檔備份,存於網際網路檔案館) on literate programming
- Haskell (頁面存檔備份,存於網際網路檔案館) literate programming
- Specification of literate programming in the Haskell Report (頁面存檔備份,存於網際網路檔案館) the accepted Haskell standard
- Noweb — A Simple, Extensible Tool for Literate Programming (頁面存檔備份,存於網際網路檔案館)
- Lp4all — A Simple Literate Programming Tool with a wiki-like markup syntax (頁面存檔備份,存於網際網路檔案館)