Remove ads

元程式設計(英語:Metaprogramming),又譯超程式設計,是指某類電腦程式的編寫,這類電腦程式編寫或者操縱其它程式(或者自身)作為它們的資料,或者在編譯時完成部分本應在執行時完成的工作。多數情況下,與手工編寫全部代碼相比,程式設計師可以獲得更高的工作效率,或者給與程式更大的靈活度去處理新的情形而無需重新編譯。

編寫元程式的語言稱之為元語言。被操縱的程式的語言稱之為「目標語言」。一門程式語言同時也是自身的元語言的能力稱之為「反射」或者「自反」。

反射是促進元程式設計的一種很有價值的語言特性。把程式語言自身作為一級資料類型(如LISPForthRebol)也很有用。支援泛型程式設計的語言也使用元程式設計能力。

元程式設計通常通過兩種方式實現。一種是通過應用程式程式設計介面(APIs)將執行時引擎的內部資訊暴露於程式碼。另一種是動態執行包含程式設計命令的字串表達式。因此,「程式能夠編寫程式」。雖然兩種方式都能用於同一種語言,但大多數語言趨向於偏向其中一種。

範例

這是一個簡單的使用bash指令碼編寫的元程式範例,同時也是一個生成式程式設計的例子:

#!/bin/bash
# metaprogram
echo '#!/bin/bash' >program
for ((I=1; I<=992; I++)) do
    echo "echo $I" >>program
done
chmod +x program

這個指令碼(或程式)生成了一個新的993行的程式來列印輸出數字1至992。這只是一個怎樣用代碼來編寫更多代碼的範例;但並不是列印一串數字最有效的方法。儘管如此,一個程式設計師可以在幾分鐘內編寫和執行這個元程式,卻生成了近1000行的代碼。

不是所有的元程式設計都需要產生式程式設計。如果一個程式可以在執行時改變或者可以使用增量編譯(如LispForthPerlPythonREBOLSmalltalkRubyPHPTclLuaGroovyFrink英語Frink (programming language)JavaScript),那麼就可以在不實際生成原始碼的情況下使用這種技術實現元程式設計。

最常見的元程式設計工具是編譯器,它可以將程式設計師使用高階語言編寫的相對短小的程式轉換為等價的匯編語言或者機器語言程式。這是最基礎的程式設計工具,在大多數情況下,直接編寫機器語言程式是不太現實的。

編譯器能夠將一種語言轉換為另一種,而其它元程式設計系統則允許以程式設計方式操縱一種語言。巨集系統即是這樣一種簡單的系統。在Microsoft Office©的程式中,巨集可以記錄一些特定的按鍵組合,並重新執行。另一方面,這些可執行代碼可以通過點擊巨集選擇介面的「編輯」按鈕獲得。

LISP恐怕是具備元程式設計能力的典範語言,不僅因為它在歷史上優先發展,更由於它的元程式設計的簡潔與強大。在Lisp元程式設計中,准參照運算子(通常是一個逗號)引入的代碼是在程式定義時而不是執行時被賦值。元程式設計語言因此等價於主程式語言,並且在需要的時候,已經存在的Lisp常式還可以直接重用於元程式設計。

在程式中嵌入直接處理程式數據的直譯器即可實現這一目的。現在已經有一些用於常用高階語言的實現,例如RemObject為Object Pascal編寫的Pascal Script

另一個很常用的元程式設計例子是lexyacc,這兩個工具用來生成詞法剖析器語法剖析器。Yacc通常用作編譯器的編譯器,生成能夠將高階語言轉換為機器語言的工具。

自產生程式是一種原始碼等於輸出的特殊的元程式。語言導向程式設計是一種強烈關注元程式設計的程式設計風格,通過領域特定語言來實現。

Remove ads

巨集用於產生式程式設計

IBM System/360及其衍生物擁有強大的組譯巨集工具,通常用於生成完整的程式或者程式片段(比如針對不同作業系統)。CICS事務處理系統也提供了組譯巨集,可以生成用於預處理階段的COBOL陳述式。

元程式設計實現

外部連結

Wikiwand in your browser!

Seamless Wikipedia browsing. On steroids.

Every time you click a link to Wikipedia, Wiktionary or Wikiquote in your browser's search results, it will show the modern Wikiwand interface.

Wikiwand extension is a five stars, simple, with minimum permission required to keep your browsing private, safe and transparent.

Remove ads