可扩展编程

可扩展编程（Extensible programming）是計算機科學的詞語，是指程式設計的風格會著重在可以擴展程式語言、編譯器、运行时系统的相關機制。可延伸程式語言（Extensible programming languages）是可以支援這種程式設計方式的程式語言，在1960年代曾是熱門研究主題，而此運動在1970年代就已邊緣化，在21世紀時此一主題又受到關注。 第一篇和可扩展编程運動有關的論文是道格拉斯·麥克羅伊在1960撰寫，有關高階程式語言巨集的論文。另一個早期對可擴展原則的說明，出現在Brooker和Morris所著，有關編譯器編譯程式（compiler-compiler）的論文。此運動中有二個具代表性，分別在1969年及1971年舉行的學術座談會，是此運動發展最熱的時期。Thomas A. Standish在1975年發表對此運動的調查文章，在本質上屬於事後的剖析。Forth算是此一運動的例外，不過也沒有被人注意到。 可延伸程式語言會包括提供基礎計算功能的基礎語言（base language），以及可以修改基礎語言的元語言。程式會包括元語言所進行的修改，以及以修改後基礎語言所撰寫的程式碼。 在此波潮流中，最著名的語言擴展技術就是巨集定義。語法修改也和可扩展编程運動有密切的關係，最終發展成適應型文法（英语：Adaptive grammar）形式主义。Lisp程式語言的群體仍和可扩展程式語言群體分開，其原因顯然如下： 任何程式語言，只要程式碼和資料在本質上可以互換，就可以視為是可延伸程式語言...由Lisp已長久當作可延伸程式語言來使用，就可以輕易的看出此一事實。 在1969的研討會中，認為Simula是可延伸程式語言。 Standish描述了三類不同的語言延伸，稱為paraphrase、orthophrase和metaphrase。（paraphrase和metaphrase原來是翻譯上的術語）。 paraphrase（改寫）會說明新功能如何用以前定義（或是將要定義）的事物來表示，以此定義新的功能。Standish的舉例提到了巨集定義、一般程序定義、語法延伸、資料定義、運算子定義以及控制結構的延伸。 Orthophrase在語言中加入一些基礎語言無法達成的功能，例如在沒有輸出入指令的基礎語言中加入輸入及輸出功能。因為此功能無法用此基礎語言表示，因此一定要用其他的語言來定義。這些擴展功能對原語言來說就是Orthophrase。這對應現代的插件。 Metaphrase會修改詮釋表示式時所用的規則。這對應現代的反射式编程。 Standish認為當時可扩展编程的失敗是因為若程式有數層的扩展，在撰寫時會格外困難。程式設計師可以在基礎語言上加上第一層的巨集。若要在此語言上加上第二層的扩展，後續的程式設計者需要熟悉基礎語言，以及第一層的扩展。若要加上第三層的扩展，程式設計者需要熟悉基礎語言、第一層扩展以及第二層扩展。取代可扩展编程運動的抽象化，其本意就是讓程式設計者 不用接觸低階的細節。 Standish雖然在1975年時將Simula歸類為可扩展程式語言，但其研究似乎沒有將比較新的，以抽象化為基礎技術算在可扩展程式語言內（只是其中對可扩展的定義，使用了非常寬的定義，抽象化在技術上是在該定義範圍內）。1978年有一份文獻提到程式抽象化的歷史，說明從電腦發明以來的相關演進，其中沒有提到巨集，也沒有提及可扩展编程運動。一直到1980年代末期，才試驗性的將巨集列在抽象化運動中（可能是因為衛生巨集的出現），其名稱為「句法抽象化」（syntactic abstraction）。 現代支援可扩展编程的系統需要提供以下的所有功能[來源請求]。 這是指所編輯的來源程式語言不能是封閉、固定、靜態不能變化的。要支援在來源程式語言加入新關鍵字、新概念或是結構的功能。有些程式語言可以用使用者定義語法加入組成元素，例如Coq、Racket、Camlp4（英语：Camlp4）、OpenC++、Seed7（英语：Seed7）、 Red（英语：Red (programming language)）、Rebol及Felix。可延伸的語法可以接受一些基礎以及固有的程式語言特性是不變的，但系統不可能只依賴這些程式語言的功能，需可以加入新的程式語言功能。 在可延伸程式設計中的編譯器，不是一個將程式原始碼轉換為二進制可執行輸出的单层系统。編譯器本身也要是可延伸的，編譯器在實質上是許多插件的組合，這些插件可以將原始程式語言的輸入轉換為任何想要的輸出。例如，可延伸的編譯器可以支援產生目的碼、程式文件、重新調整格式的原始碼，或是其他想要的輸出。編譯器的架構需允許使用者進入其編譯流程內，在編譯流程的各步驟可以提供其他的處理任務。 若考慮將原始程碼翻譯成電腦可以執行檔案的這個任務，可延伸編譯器需要有： 在其功能的絕大部份層面，使用插件或是元件架構。 確認要編譯的語言（或是語言變體），配置適當的插件來的辨認及確認其語言。 依各來源語言的型式語言規範，在句法及結構上確認。 呼叫適當的確認插件，以協助來源語言的語意確認 允許用戶者在不同種類的程式碼產生器中選擇，可以依處理器、作業系統、虛擬機及其他作業環境的不同，生成適合的執行檔。 提供錯誤訊息產生的功能，以及相關的延伸。 可以在抽象語法樹（AST）中加入新的節點種類。 抽象語法樹的節點中允許有新的值。 允許其他種類，連接節點的邊。 允許輸入抽象語法樹的轉換，可以部份或全部來自外部的程式。 允許輸入抽象語法樹的翻譯，可以部份或全部交由外部的程式。 協助內部和外部程式之間的資訊流，因為他們都會將抽象語法樹轉換或是翻譯為其他的抽象語法樹，或是其他表現方式。 可延伸程式系統在執行時的環境要允許程式語言增加可處理的運算。例如，某個使用字节码直譯器的系統，需要允許定義新的字节码。在可延伸語法下，可以接受少數基礎運算或是固有運算是不能變的，不過這些固有運算要可以重載或是擴充，以便支援新增的行為。 可延伸程式系統需將程式視為要處理的資料。程式中需要完全沒有格式化相關的資訊。要給使用者的程式 視覺顯示以及編輯都應該是可延伸編譯器所支持的翻譯函式，將程式資料轉換成適合顯示或是編輯的格式。此翻譯會是雙向的翻譯。雙向翻譯的特性很重要，因為需要可以用許多不同的方式，輕鬆的處理可延伸程式。若只能用來源語言來編輯及檢視，然後就翻譯成機械碼，無法再翻譯成其他的格式，這是無法接受的。透過將來源輸入和其處理（格式、儲存、顯示及編輯）的格式分離，可以對程式進行各種不同的處理。 可延伸程式系統需要可以用原始來源語言來進行除錯，即使是程式在變成可執行檔的過程有進行轉換或是延伸也是一樣。最為人知的是：不可以假設運行時資料只能用結構或是陣列的方式顯示。除錯器（更準確的說法是「程式檢查器」）需要讓運行時資料以適合其來源語言的形式來呈現。例如，若程式語言支援业务过程或是工作流的資料結構，需要將資料結構用插件表示為流程圖或是其他適合的型式。 Camlp4（英语：Camlp4） Felix Nemerle Seed7（英语：Seed7） Rebol Red（英语：Red (programming language)） Ruby（元编程） OpenC++ XML Forth Lisp Racket Scheme Lua PL/I Smalltalk 適應型文法（英语：Adaptive grammar） 面向语言的程序设计 同像性 Standish, Thomas A., "Extensibility in Programming Language Design", SIGPLAN Notices 10 no. 7 (July 1975), pp. 18–21. Gregory V. Wilson, "Extensible Programming for the 21st Century （页面存档备份，存于互联网档案馆）", ACM Queue 2 no. 9 (Dec/Jan 2004–2005). Sammet, Jean E., Programming Languages: History and Fundamentals, Prentice-Hall, 1969, section III.7.2 McIlroy, M.D., "Macro Instruction Extensions of Compiler Languages", Communications of the ACM 3 no. 4 (April 1960), pp. 214–220. Brooker, R.A. and Morris, D., "A General Translation Program for Phrase Structure Languages", Journal of the ACM 9 no. 1 (January 1962), pp. 1–10. The paper was received in 1960. Christensen, C. and Shaw, C.J., eds., Proceedings of the Extensible Languages Symposium, SIGPLAN Notices 4 no. 8 (August 1969). Schuman, S.A., ed., Proceedings of the International Symposium on Extensible Languages, SIGPLAN Notices 6 no. 12 (December 1971). Harrison, M.C., in "Panel on the Concept of Extensibility", pp. 53–54 of the 1969 symposium. Guarino, L.R., "The Evolution of Abstraction in Programming Languages[失效連結]", CMU-CS-78-120, Department of Computer Science, Carnegie-Mellon University, Pennsylvania, 22 May 1978. Gabriel, Richard P., ed., "Draft Report on Requirements for a Common Prototyping System", SIGPLAN Notices 24 no. 3 (March 1989), pp. 93ff. Syntax extensions and notation scopes – Coq 8.17.0 documentation. coq.inria.fr. [2023-05-25]. （原始内容存档于2023-12-12）.  Zingaro, Daniel, "Modern Extensible Languages （页面存档备份，存于互联网档案馆）", SQRL Report 47 McMaster University (October 2007), page 16.