热门问题
时间线
聊天
视角
文學程式設計
来自维基百科,自由的百科全书
Remove ads
文學式程式設計(英語:literate programming)是由高德納提出的程式設計方法,希望能用來取代結構化程式設計範式。[1]
![]() | 此條目需要精通或熟悉電腦科學的編者參與及協助編輯。 |
此條目目前正依照其他維基百科上的內容進行翻譯。 (2022年8月4日) |
正如高德納所構想的那樣,文學程式設計範式不同於傳統的由電腦強加的編寫程式的方式和順序,而代之以讓程式設計師用他們自己思維內在的邏輯和流程所要求的順序開發程式。[2]文學程式設計自由地表達邏輯,而且它用人類日常使用的語言寫出來,就好像一篇文章一樣,文章裡包括用來隱藏抽象的巨集和傳統的原始碼。文學程式設計工具用來從文學原始檔中獲得兩種表達方式,一種用於電腦進一步的編譯和執行,稱作「繞出」(tangled)的代碼,一種用于格式化文件,稱作從文學原始碼中「織出」(woven)。[3]。雖然第一代文學程式設計工具特定於電腦語言,但後來的工具可以不依賴具體語言,並且存在於比程式語言更高的層次中。
Remove ads
概念
文學程式是用自然語言(比如英語)寫出來的對程式邏輯的解釋,程式中交織點綴著巨集和傳統原始碼段。在文學程式設計的原始檔中,巨集很簡單,它或與標題類似,或是解決程式設計問題時用人類語言描述抽象的解釋性短語。它把代碼段或更低層次的巨集隱藏了起來,且與電腦科學教學時經常用到的,用虛擬碼寫的演算法相似。這些任意解釋的短語成為新的精確的運算子,運算子由程式設計師在執行過程中建立,組成了在基本程式語言之上的「元語言」。 預處理器用於替換任意層級,說得更準確些是「在'網'和巨集之間建立聯絡」[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]
Remove ads
文學程式設計工具
第一個發布的文學程式設計環境是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 工具之一強大。
Remove ads
參見
- Sweave - an example of use of the "noweb"-like Literate Programming tool inside the R language for creation of dynamic statistical reports
參考文獻
延伸閱讀
外部連結
Wikiwand - on
Seamless Wikipedia browsing. On steroids.
Remove ads