我在ployglot programming on the Java platform上閱讀TheServerSide上的一篇文章。文章中的一些評論將元編程稱爲生成代碼的能力(可能即時)。元編程究竟是什麼?
元編程能夠在運行中生成代碼,還是能夠在運行時將方法和屬性注入現有對象(如Python,Ruby和Groovy允許的一些動態語言)。
我在ployglot programming on the Java platform上閱讀TheServerSide上的一篇文章。文章中的一些評論將元編程稱爲生成代碼的能力(可能即時)。元編程究竟是什麼?
元編程能夠在運行中生成代碼,還是能夠在運行時將方法和屬性注入現有對象(如Python,Ruby和Groovy允許的一些動態語言)。
元編程是指程序擁有自身知識或可以操縱自己的各種方式。
在像C#這樣的語言中,反射是元編程的一種形式,因爲程序可以檢查有關自身的信息。例如返回一個對象的所有屬性的列表。在ActionScript等語言中,您可以在運行時評估函數以創建新程序,例如eval(「x」+ i).DoSomething()會在i爲1時影響名爲x1的對象,在i爲2時影響名爲x2的對象。最後,元編程的另一種常見形式是程序能夠以非平凡的方式改變自己。 LISP因此而聞名,並且是Paul Graham十年前所倡導的。我得看看他的一些具體的散文。但想法是,該計劃將根據其狀態改變該計劃的另一部分。這允許一定程度的靈活性在運行時作出決定,這在當今大多數流行語言中是非常困難的。
還值得注意的是,在直接裝配編程的良好日子裏,在運行時改變自身的程序是必要的,也是非常普遍的。
從保羅·格雷厄姆的文章"What Made Lisp Different":
許多語言有一種叫 宏。但Lisp宏是獨一無二的。並且 相信與否,他們所做的是與括號相關的 。 Lisp的 設計者並沒有把所有這些 括號的語言恰好變成 的不同。對Blub程序員來說, Lisp代碼看起來很奇怪。但那些圓括號在那裏是有原因的。 它們是Lisp 與其他語言之間的基本區別 的外在證據。
Lisp代碼是由Lisp數據 對象製成的。而不是簡單的意義 源文件包含 字符,字符串是該語言支持的 數據類型之一。 Lisp代碼在被 解析器讀取後,由可以遍歷的數據結構 組成。
如果你瞭解編譯器的工作, 到底發生了什麼就如何與其說是 Lisp的有一個奇怪的語法爲 Lisp有沒有語法。在分析其他 語言時,編譯器在編譯器內生成 的分析樹中編寫程序 。但是這些解析 樹木可以完全訪問您的 程序。你可以編寫程序 操縱它們。在Lisp中,這些 程序被稱爲宏。他們是編寫程序的 程序。
寫程序的程序? 你會想要這樣做嗎?如果您想在Cobol中,經常不是 。所有 的時間,如果你認爲在Lisp。它 會很方便,如果我可以 舉一個強大的宏, 的例子,並說!那個怎麼樣?但是,如果我做了 ,那麼對於不知道 Lisp的人來說,它看起來就像是 胡言亂語;這裏沒有空間來解釋 所有你需要知道的知識, 明白這是什麼意思。在Ansi Common Lisp我想,我可以搬東西 沿快,即使如此 我沒有得到宏直到第160
但我想我可以給人一種 的說法,可能是有說服力的。 Viaweb編輯器的 源代碼是 ,可能大約有20-25%的宏。宏 比普通的Lisp 功能更難寫,並且它被認爲是 不好用的樣式,當它們不是 時需要使用它們。因此,代碼 中的每個宏都存在,因爲它必須是。 這意味着什麼 在這個程序中的代碼至少20-25%是做 你不能輕易做任何其他語言 的事情。然而,懷疑 Blub程序員可能對我的 聲稱 Lisp的神祕力量,這應該讓他好奇。 我們沒有爲我們的 自己的娛樂寫這個代碼。我們是一個微小的初創公司, 編程盡我們所能在 爲了把我們和我們的競爭對手之間的技術障礙 。
一個可疑的人可能會開始 想知道這裏是否有一些相關 。我們的代碼中有很大一部分是 ,在其他語言中很難做到 。由此產生的 軟件做了我們的競爭對手 軟件無法做到的事情。也許有 某種連接。我鼓勵 你遵循該線程。有可能 更多地是那個在柺杖上沿着 蹣跚而行的老人。
元編程是指編寫或操作其他程序(或其本身)作爲其數據的計算機程序,或者是在運行時執行部分工作的計算機程序,否則將在編譯時完成。在很多情況下,這允許程序員在與手動編寫所有代碼相同的時間內完成更多的工作,或者使程序更加靈活地處理新情況而無需重新編譯。 (Source。)
基本上,它編寫的代碼可以輸出更多的代碼,它可以運行來完成某個目標。這通常在相同的語言(使用JavaScript創建一個JavaScript字符串,然後eval
它)或發出另一種語言(使用.NET創建一個Windows批處理文件)完成。
wikipedia在這個話題上有一篇不錯的文章。一個人不必對某些東西進行運行時修改就可以作爲元編程。例如,許多人使用C++模板在編譯時進行元編程。
元編程正在編寫一個輸出另一個程序的程序。這是像Lisp這樣的語言非常擅長的。使用Ruby,Lisp,Scheme等支持真正的宏(不是C++宏,而是可以操縱他們輸出的代碼的語言)的語言比使用Java語言更容易。
一個實現是創建一個「域特定語言」,這是一種增強編程語言以完成特定任務的方式。如果做得正確,它可以非常強大。 Ruby on Rails就是這類編程的一個很好的例子。
如果您有興趣探索此方法,請參閱Structure and Interpretation of Computer Programs這是涵蓋該主題的開創性書籍之一。
那麼,元編程只是編程,但它基本上是「編寫代碼,編寫代碼」。
當程序可以觀察和修改自己的結構和行爲時,您提到的能力稱爲反射,它是一種元編程。
動態類型語言,具有強大的運行時反射的功能,通過這些語言的解釋性質成爲可能......
靜態類型語言也有強大的元編程技術,例如C++ template metaprogramming ...
這只是我個人的觀點,這可能是元編程最自由的定義。
我認爲它包括:
我想你可以通過以下任何一種方式與其組合:
偉大的問題。我很抱歉地看到,目前沒有任何答案能夠正確回答你的問題。也許我可以幫助...
元程序的定義確實很簡單:它意味着程序操縱程序。
您接受的答案是指操作自己的程序。這些確實是元程序,但它們是所有元程序的一個子集。
所有:
是元程序。所以GCC compiler是元程序,CPython interpreter是元程序,Mathematica computer algebra system是元程序,Coq theorem prover是元程序等。
其他答案已經斷言元程序是生成其他程序的程序。這些確實是元程序,但它們又是所有元程序的一個子集。 Fastest Fourier Transform in the West(FFTW)庫是這種元程序的一個例子。源代碼主要編寫在OCaml中,它生成一些C代碼(稱爲codelet),這些代碼組合在一起以創建針對特定機器優化的高性能Fast Fourier Transform例程。該庫實際上用於在Matlab中提供FFT例程。自FORTRAN早期開始,人們一直在編寫程序來生成數十年的數值方法。
集成對元編程支持的第一種編程語言是在20世紀50年代後期的LISt處理器(LISP)語言。 LISP 1.5包含了一些使元編程更容易的功能。首先,LISP的核心數據類型是嵌套列表,即像(a (b c) d)
這樣的樹,這意味着任何LISP代碼都可以本地表示爲數據結構。這就是所謂的homoiconicity。其次,可以使用QUOTE輕鬆地將LISP代碼轉換爲數據。例如,(+ 1 2 3)
增加1 + 2 + 3,(QUOTE (+ 1 2 3))
創建一個表達式,在評估時增加1 + 2 + 3。第三,LISP提供了一個元循環評估器,允許您使用宿主解釋器或編譯器在運行時評估LISP代碼,包括運行時生成的LISP代碼。 LISP的後代包括Scheme和Clojure。在所有這些語言中,元編程最常見的形式是通過宏來修改自己的程序。
在20世紀70年代,羅賓·米爾納開發了MetaLanguage(ML),其演變成ML系列的編程語言,其中包括Standard ML和OCaml和強烈的影響Haskell和F#。這些語言可以很容易地表達其他語言。在這些語言中,元語言最常見的形式是詞法分析器,解析器,解釋器和編譯器。
1994年,Erwin Unruh discovered that the C++ template system was Turing complete and could be used to execute arbitrary programs at compile time。 C++模板元編程爲未經洗刷的羣體帶來元編程(ab),用於許多不同的事情,包括在Blitz++ library中生成數值方法。
您可能感興趣的這個答案http://stackoverflow.com/questions/2565572/metaprogramming-self-explanatory-code-tutorials-articles-books/2566561#2566561 – ewernli 2012-04-10 09:01:37
@ewernli:這個答案實際上比任何這裏的答案! – 2017-02-14 07:12:41