程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 冒號課堂§5.3:動態語言

冒號課堂§5.3:動態語言

編輯:關於JAVA

第五課 語言小談(3)

5.3動態語言——披著彩衣飛舞的腳本語言

故凡天下之理,欲向動上求靜,靜上求動      ——《蔡牧堂·發微論》

關鍵詞:   動態語言,靜態語言,腳本語言

摘要:  動態語言簡談

!預覽

·程序是為終端用戶服務的,而腳本是為程序員服務的

·動態語言秉承的一個理念是:優化人的時間而不是機器的時間

·待靜態語言披盔戴甲、備馬抬槍之際,動態語言已衣袂飄飄,長劍出手了

·當腳本語言披上動態語言的彩衣,昔日不起眼的毛毛蟲便羽化成碟,開始飄舞在眾人追逐的目光之中

?提問

·腳本與程序的區別是什麼?

·腳本語言有什麼特點?為什麼適合作粘合語言?

·動態語言有什麼特點?它與腳本語言究竟有什麼分別?

·動態語言也能用於大型應用開發嗎?

·動態語言會最終取代靜態語言嗎?

:講解

歎號急不可耐地問:“現在可以談動態語言了吧?”

冒號感言:“曾幾何時,動態語言還只是陪太子讀書的角色,那時候它們的名字是‘腳本語言’。近來卻迅速崛起,俨然有與靜態語言分庭抗禮之勢。”

問號忍不住問道:“動態語言與腳本語言是一回事嗎?”

“相比動態語言定義上的模糊,腳本語言的概念還是比較明確的。”冒號回避直接給出答案,“腳本(script)的提法,是為了區別於一般的程序(program)。Perl的發明者Larry Wall不愧為語言學家,對此有一個精彩的說法:‘A script is what you give the actors, a program is what you give the audience’。直譯為:腳本是給演員看的,節目是給觀眾看的。此言妙在一語雙關——program兼有‘節目’和‘程序’的意思。”

句號領會其意:“這裡的演員指的是程序員,觀眾指的是用戶。換言之,程序是為終端用戶服務的,而腳本是為程序員服務的。”

“正解!”冒號肯定道,“腳本最常見的形式是殼腳本(shell script),在非Unix類的操作系統中也稱為批處理文件(batch file)。”

“批處理文件倒是很熟悉,殼腳本聽起來就怪怪的。”逗號嘀咕著。

“那是因為你在Windows的世界裡長大,聽不慣Unix的方言。”冒號一語道破緣由,“操作系統的內核稱為核(kernel),出於安全考慮不便直接與用戶交互,因此裹上一層殼(shell),即人們常說的命令行解釋器(command line interpreter)。殼腳本是在殼上運行的腳本,擴展了命令行下可執行的命令。它最初主要是內建(built-in)命令的組合,用於系統程序的調度,是系統管理員的必備武器。其後,殼腳本也發展到用於應用程序的調度、連接、調試等,成為粘合(glue)語言。”

逗號不禁有些疑問:“難道一般的程序語言如C之類的不能作此用嗎?”

引號回應道:“這些語言通常需要‘編寫-編譯-鏈接-運行’的循環過程,十分繁瑣。腳本語言編寫後即可運行,快捷方便得多。”

冒號點點頭:“不錯,既然腳本主要用於整合其他程序,本身並不占用太多的資源,同時邏輯也不太復雜,因此腳本語言注重簡潔、實用,語法要求不那麼嚴格,性能上的要求也不高。除殼腳本外,還有一些專用於文本處理(text processing)的語言或工具如AWK、sed和grep等,多用於讀寫配置文件和日志文件、過濾處理各種程序的輸入和輸出,對於整合各種程序也非常實用。隨著對腳本語言需求的增長,其局限性日益突出,以Perl為代表的高級腳本語言便應運而生了。Perl在殼腳本、AWK、sed的基礎上,融合了命令式的C與函數式的Lisp的特征,漸漸成為最流行的腳本語言之一。”

問號注意到:“JavaScript是浏覽器端的腳本,來路似乎有些不同。”

冒號解釋道:“除了命令行程序外,腳本語言在其他的應用程序中也身影頻現,如圖形界面應用、多媒體應用、網絡應用等。尤其是網絡應用,成為滋生和繁榮腳本語言最肥沃的土壤。例如:Perl非常廣泛地用於網絡服務器端的CGI編程;PHP更是專為動態網頁而設計的語言;Ruby雖與Java同歲,但真正開始風行得益於網絡應用框架Ruby on Rails的成功;至於JavaScript,長期被邊緣化為網頁設計人員的語言,是web2.0的新寵AJAX真正將其帶入程序員的視線。”

逗號有些好奇:“什麼時候腳本語言變成了動態語言呢?”

“盡管動態語言並無確切的定義,但不是所有的腳本語言都能稱作動態語言的——比如Bash之類的殼腳本語言(shell script language);另一方面,也不是所有的動態語言天生就是為腳本服務的——比如Lisp[1]。不妨這麼理解,腳本語言以語言的實際用途為標志,動態語言以語言的語法特征為標志。”冒號回答,“單從用途上看,一個腳本語言如果不再局限於命令行工具和粘合工具,從專用語言發展為通用語言,並能勝任復雜的應用開發,或許更有資格歸為動態語言。”

句號發現:“動態語言似乎對字符處理都特別擅長。”

冒號道:“腳本語言與一般程序一個不同之處是,它一般是面向字符而非數值的,因為字符是最通用的接口,正好發揮其粘合作用,而數值運算對性能要求較高,多由核心程序來完成。動態語言繼承了這個特點,並且除了正則表達式(regular expression)外,為字符串、數組、列表、集合、映射等常用結構提供了豐富簡潔的運算,遠比靜態語言依賴於庫(library)的方便自然得多。”

歎號問:“我們清楚了腳本語言中‘腳本’的來歷,那動態語言中‘動態’又體現在何處呢?”

“問得好!”冒號聞言,正中下懷,“再從用法上看,動態語言能在運行中增加或改變數據結構、函數定義、對象行為或指令流程等。如果說動態類型語言的動態體現在類型上,動態語言的動態則體現在結構和功能上。相比而言,靜態語言雖然也可能實現同樣的效果,但既不方便也不自然[2]。另外不容忽視的一點是,動態語言大多是開源的,其本身的發展也更具動態性。”

引號非常注重理論:“動態語言的語法特征有那些?”

“動態語言秉承的一個理念是:優化人的時間而不是機器的時間。為提高人的生產率,寧肯犧牲部分的程序性能或者購買更高配置的硬件。由於硬件相對於人件一直在貶值,該理念便有了合理的現實基礎。”冒號講述著,“從語法上看,動態語言為了更好地粘合來自不同系統、不同語言的程序,對類型的要求一般不如靜態語言那麼嚴格,代碼更加簡潔自由,故而多為動態類型的和弱類型的,天然支持泛型式編程。當然這不是絕對的,比如Groovy也支持靜態類型,Scala完全是靜態類型的,Python一般認為是強類型的。大多數動態語言支持eval函數,能動態執行任意字符串形式的代碼,並有豐富的反射(reflection)機制,天然支持元編程。動態語言很多還支持包括高階函數(high-order function)和閉包(closure)等在內的函數式編程。此外,大多動態語言也支持對象式編程,如Python、Ruby、Perl 5、PHP 3等。”

句號補充道:“許多動態語言還支持過程式編程和並發式編程,簡直把主要的編程范式一網打盡了!”

“其實Python、Ruby和Groovy等還可以進行切面式編程,這對於支持元編程的動態語言來說非常自然,因為切面式編程一般都是通過元編程來實現的。”冒號進一步指出,“而邏輯式編程語言的代表Prolog,同樣有動態語言的特征。至於事件驅動式編程嘛,對支持callback的語言來說都不是難事。”

引號高興地看到:“九大編程范式無一漏網啊!”

歎號較為感性:“靜態語言給人的感覺是沉穩持重,而動態語言則活潑輕快。如果同時用靜態語言和動態語言編程,豈不培養出雙重人格?”

“程序員本就是雙重人格的。”冒號淡淡地說,“你總結得沒錯,兩類語言的風格的確大相異趣:待靜態語言披盔戴甲、備馬抬槍之際,動態語言已衣袂飄飄,長劍出手了。不過,如果是應付強敵的長期大規模作戰,靜態語言還是有優勢的。”

引號聽聲辨音:“這意味著動態語言不適用大型應用開發嗎?“

“這麼說未免有些武斷。”冒號並不同意,“誠然,動態語言的語法比較寬松,相對容易出錯。但也有人辯稱,動態語言的代碼量少於相應的靜態語言,bug應該更少。有人認為動態語言調試不如靜態語言方便,有人卻說隨著IDE的日益強大,出錯幾率和找錯成本也在減少。談到運行效率,動態語言雖然多為解釋型語言(interpreted language),但許多也提供了與Java類似的字節碼編譯(bytecode compilation)甚至JIT編譯(just-in-time compilation)。動態語言在某方面甚至還更勝一籌:譬如一個類的接口如果發生變動,在靜態語言中所有該類的子類和一些相關類都可能需要重新編譯、連接,這在大型應用中是非常耗時的,而動態語言則大可不必,這當然不足為奇——在它眼裡類結構本來就是能動態改變的。除此之外,越是大型的程序,越耗費人力和時間成本,客戶需求的變化也越大,因而對程序的靈活性、適應性和開發周期提出了更高的要求。動態語言在這些方面比靜態語言更有優勢,並且還能作為快速原型(rapid prototyping)開發的工具。”

“快速原型開發?”問號一臉的疑惑。

冒號簡作介紹:“這是一種軟件開發的方式。舉例來說,為了快速搭建一個系統,以適應不斷變化的客戶需要,可以先采用開發效率更高的動態語言。在交付時再將其轉化為編譯型的靜態語言。如果系統對性能的要求不高,這種轉化至多是局部的。有的干脆一字不易,不僅省了當下的時間,以後維護起來也更方便。”

逗號耍起了貧嘴:“這就叫:替補變成了主力,配角變成了主角,媳婦熬成了婆婆。”

歎號開始擔憂起來:“聽您這意思,動態語言優點突出而弱點並不突出,這樣下去靜態語言還有市場嗎?”

冒號坦然道:“動態語言小快靈的風格的確吸引了越來越多人的注意,也漸漸走入靜態語言的世界。Java平台和.Net平台不僅為Ruby和Python等動態語言鋪設了跑道,而且為培植諸如Groovy等動態語言提供了土壤。同時,Java和C#本身也融進了越來越多的動態特征。”

句號斷言:“靜態語言這種融合性結合內在的安全性、穩定性,以及較高的性能、成熟度和接受度,都決定了它不可能被動態語言完全取代。”

“對!”冒號堅定地表示贊同,“當腳本語言披上動態語言的彩衣,昔日不起眼的毛毛蟲便羽化成碟,開始飄舞在眾人追逐的目光之中。但靜態語言也絕不會淡出人們的視線,它如矯健的蒼鷹,依然有搏擊長空的雄力。程序員只要保持嚴謹的作風和開放的心態,既有穩如泰山的馬步,又有一躍凌空的飛腿,靜如處子,動如脫兔,如履平地般游走於高高的梅花樁上,絕無跌落之虞。”

一股豪情在眾人心中蕩漾開來。

冒號看了看時間,斂起眼中精光,同時收起話匣:“關於動態語言,今天還是先簡單談到這裡吧。”

,插語

[1] Lisp本身以及一些變種如Emacs Lisp、AutoLISP等也能作為腳本語言,但那畢竟不是Lisp語言的初衷。

[2] 一些設計模式(如裝飾模式、訪問者模式等)就是為了賦予靜態語言一定的動態特征。

。總結 

程序是為終端用戶服務的,腳本是為程序員服務的。

腳本語言一般是解釋型語言,不需要通過“編寫-編譯-鏈接-運行”的循環圈,便利快捷,加之簡潔寬松的語法、面向字符的特性以及較強的文本處理能力,尤其適合作為粘合語言,多用於系統管理和集成。

腳本語言與動態語言盡管並不完全重合,但更多地還是提法上的區別。前者強調作為命令行工具和粘合工具的語言用途,後者強調動態的語言特征。當腳本語言不再局限於粘合語言,從專用語言發展為通用語言,並且勝任復雜的應用開發的時候,動態語言的提法顯然更加合理。

動態語言能在程序運行期間改變數據結構、函數定義、對象行為或指令流程等,相比靜態語言在結構和功能上的更具動態性。

動態語言重在優化人工時間而非機器時間,因此相比靜態語言,其開發效率較高,但運行效率較低。

動態語言的以下特點決定了它在大型應用開發中的價值:代碼量較少,從一定程度減輕了維護難度;不少提供了字節碼編譯或JIT編譯,彌補了運行效率上的不足;一些模塊的結構和功能上的變化不會導致相關模塊的重新編譯和連接;具有靈活、適應力強和開發周期短的特點,能快速響應客戶需求的變化,並且適合快速原型開發。

靜態語言安全穩定、性能優越、成熟普及,並且逐漸開始吸納動態語言的一些優點,這些都決定了它不可能被後者完全替代。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved