冒號和他的學(xué)生們(連載10)——超級范式
冒號和他的學(xué)生們
——程序員提高班紀(jì)事
- 超級范式
智能繁衍:機器人生產(chǎn)機器人 ——題記
引號忽然想起一事,問道:“有一本名為《C++模版元編程》的書,既然提到了模板,想來也屬于泛型編程吧?”
冒號答道:“模板元編程即Template Metaprogramming,與GP密切相關(guān)但自成一派,隸屬于另一種編程范式——元編程(Metaprogramming),簡稱MP。這里的前綴‘meta-’常譯作‘元’,其實就是‘超級’、‘行而上’的意思。比如,元數(shù)據(jù)(Metadata)是關(guān)于數(shù)據(jù)的數(shù)據(jù),元對象(Metaobject)是關(guān)于對象的對象,依此類推,元編程自然是關(guān)于程序的程序,或者說是編寫、操縱程序的程序。”
嘆號皺著眉:“聽著有點繞。”
冒號投影出另一段代碼——
C++(元編程):
template <int N>
struct factorial
{
enum { value = N * factorial<N - 1>::value };
};
template <> // 特化(specialization)
struct factorial<0> // 遞歸中止
{
enum { value = 1 };
};
void main()
{
cout << factorial<5>::value << endl; // 等價于cout << 120 << endl;
}
“以上用模板元編程實現(xiàn)了階乘運算。”冒號講解道,“與前面三種基本范式的階乘實現(xiàn)有著根本的不同:這里階乘的值是在編譯時而非運行時計算出來的。換句話說,這段代碼以模板形式通過編譯器生成了新的代碼,并在編譯期間獲得執(zhí)行。”
嘆號不解:“這又說明什么呢?”
冒號并不直接回答:“假設(shè)你需要批量處理用戶文檔,其格式結(jié)構(gòu)預(yù)先給定,但既不像CSV(逗號分隔)那么簡單,也不像XML那么標(biāo)準(zhǔn),并且用戶隨時可能改變格式標(biāo)準(zhǔn),請問如何設(shè)計這段程序?”
嘆號略一思索,便回答:“三大模塊:閱讀器讀出輸入文檔,解析器按照格式標(biāo)準(zhǔn)去解析,處理器對解析結(jié)果進(jìn)行處理。”
“顯然關(guān)鍵在解析器,如果你是從頭做起,那么問題至少有四。”冒號扳著指頭數(shù):“第一、費時寫解析器代碼;第二、費時調(diào)試解析器代碼;第三、如果用戶更改格式標(biāo)準(zhǔn),你得重復(fù)做上兩件事;第四、如果這段程序是大型程序的一部分,任何改動都可能意味著軟件的重新編譯、連接、測試、打包、部署等等。如果因為你的緣故公司不得不頻頻發(fā)布補丁包的話,你的飯碗恐怕是朝不保夕了。”
還是句號機靈:“既然談到了元編程,一定是利用元編程,根據(jù)不同的格式標(biāo)準(zhǔn)自動生成相應(yīng)的解析器代碼。不過——此法雖一勞永逸,但難度似乎不小啊。”
“思路對頭!”冒號贊許道,“大家聽說過Lex和Yacc嗎?它們能根據(jù)格式標(biāo)準(zhǔn)生成相應(yīng)的解析器代碼。更妙的是,格式標(biāo)準(zhǔn)不限于靜態(tài)數(shù)據(jù),甚至可以含有動態(tài)指令!這意味著用戶不僅能定義業(yè)務(wù)數(shù)據(jù)格式,還能定義業(yè)務(wù)流程乃至領(lǐng)域特定語言DSL(Domain Specific Language),而這其實涉及到另一種編程范式:語言導(dǎo)向式編程(Language-Oriented Programming)。如果在此基礎(chǔ)上再用圖形界面包裝一下,那么你的客戶會欣喜地發(fā)現(xiàn),他們的經(jīng)理只要點點鼠標(biāo)就可以改變整個業(yè)務(wù)流程了,而這一切不僅不需要軟件開發(fā)方的參與,連本公司的技術(shù)人員也免了。這時候倒是你的老板發(fā)愁了:你的設(shè)計太過完美,客戶的后續(xù)開發(fā)費怕是賺不到了。”
眾人一樂。
冒號續(xù)道:“如果知道Lex和Yacc本來就是編寫編譯器和解釋器的工具,你就不會驚訝于它們的強大了。順帶說一句,編譯器本身就是元編程的典型范例——把高級語言轉(zhuǎn)化為匯編語言或機器語言的程序,不就是能寫程序的程序嗎?其實元編程的例子比比皆是:許多IDE如Visual Studio、Delphi、Eclipse等均能通過向?qū)А⑼戏趴丶确绞阶詣由纱a;UML建模工具將類圖轉(zhuǎn)換為代碼;Servlet引擎將JSP轉(zhuǎn)換為Java代碼等等。”
逗號恍然大悟:“原來元編程就是編寫能自動生成源代碼的程序。”
“也不盡然。”冒號修正道,“自動生成源代碼的編程也屬于另一種編程范式——生成式編程(Generative Programming)的范疇。有的元編程雖不生成源代碼,卻能修改程序。從低級的匯編語言到一些高級的動態(tài)語言如Perl、Python、Ruby、JavaScript、Lisp、Prolog等均支持此類功能。”
問號問道:“編寫病毒算不算元編程?”
“編寫一個只是刪除或感染文件的病毒,不必用到元編程。”冒號應(yīng)道,“但如果要求此病毒能自我變異,那就需要元編程了。”
引號自言自語:“程序的程序,就是程序的平方。”
“也可以是程序的立方,四次方……理論上是無限次方。元程序?qū)⒊绦蜃鳛閿?shù)據(jù)來對待,能自我發(fā)現(xiàn)和自我賦權(quán),有著其他程序所不具備的自覺性、自適應(yīng)性和智能性,可以說是一種最高級的程序。它要求編程者超越常規(guī)的編程思維,在一種嶄新的高度上理解編程。想象一下,”冒號激情勃發(fā),“如果有一天機器人能自我學(xué)習(xí)、自我完善,甚至能生產(chǎn)機器人,實現(xiàn)‘智能繁衍’,是不是很美妙?”
“我怎么覺得特恐怖呢?”嘆號此言令人忍俊不禁。
posted on 2008-05-10 00:02 鄭暉 閱讀(2023) 評論(3) 編輯 收藏 所屬分類: 冒號和他的學(xué)生們