對於做 iOS 的同行們來說,動態語言這個詞再熟悉不過。那麼到底什麼是動態語言呢?到底動態語言和靜態語言有什麼區別呢?
維基百科說:
Dynamic programming language, in computer science, is a class of high-level programming languages which, at runtime, execute many common programming behaviors that static programming languages perform during compilation. These behaviors could include extension of the program, by adding new code, by extending objects and definitions, or by modifying the type system.
百度百科說:
動態語言,是指程序在運行時可以改變其結構:新的函數可以被引進,已有的函數可以被刪除等在結構上的變化。
然而這些都是對用法和現象上的描述。例如在 Objective-C 中調用了A函數。但是我到底是不是真的會調用A函數呢?不一定。真正調用到什麼函數是運行時決定的而非編譯時決定的。
這個概念想必大家都聽膩了,今天換個角度來說。例如維基百科在「Dynamic programming language」詞條第一段就提到的Lisp
。Lisp
是動態語言,它可以做到自更新,程序在運行過程中自己維護自己,自己更新自己。然而它的編譯器卻是可以被C語言實現的,而C/C++卻是靜態語言。這就意味著Lisp
的動態性,在C/C++上是完全可以實現的。
這是個非常有意思的問題,Lisp
的動態性是靜態語言賦予的。那麼我完全可以用C/C++實現一個"dynamic C/C++"的編譯器,新語言編寫時全部使用C/C++的語法,在編譯代碼時將代碼調用全部翻譯成類似 Objective-C 中的msg_send
形式,在運行時動態的調用函數指針,那麼這時候的C/C++也獲得了動態性。這樣看來,動態性完全跟語言本身沒有關系,動態能力是編譯器賦予的。
所以,我得出的結論是:所謂語言的動態性是編譯器賦予的,和語言本身無關。
另一個小話題是關於語言本身。當一個語言能夠自己實現自己的時候,也就意味著這門語言滿足了某完備性(同事說的,沒記住)。語言到達這個層面後就是平等的了。就像C語言,你說C是靜態語言,那好,我首先在程序裡用C實現一個 Objective-C Runtime,之後程序的代碼都在這個 Runtime 上運行,那這時候你還能說C語言是靜態語言嗎?
經過昨晚被大神們的批判,澄清一下:
Objective-C 是動態語言!
Objective-C 是動態語言!
Objective-C 是動態語言!
Objective-C 的動態性是怎麼獲得的呢?這裡用一下陽神的圖:
這是Xcode的編譯器結構,簡單分為三層:
clang
將代碼翻譯成 IR 語言的過程。
優化過程。
IR 語言翻譯成機器碼過程。
在第一個過程中,有一個 oc 代碼跟 Runtime 庫進行對接的過程,即翻譯成msg_send
形式,將函數調用都翻譯成這個形式以後再進入 IR 語言翻譯階段。因此 Objective-C 的動態性是在這一步獲得的。
因此關於這個問題,殿神「酷酷的哀殿」有個更准確些的說法:
Objective-C 的動態性是由 runtime 相關的庫賦予的。
當然其他語言也完全可以運行在一個 Runtime 庫上而獲得動態性,由於多數高級語言的誕生都對應著一種編譯器,因此將編譯器的特性概括進語言裡講,也不是不可以。