動態語言

動態編程語言是高級編程語言的一個類別，在計算機科學領域已被廣泛應用。它是一類在運行時可以改變其結構的語言：例如新的函數、對象、甚至代碼可以被引進，已有的函數可以被刪除或是其他結構上的變化。動態語言目前非常具有活力。眾所周知的ECMAScript（JavaScript）便是一個動態語言，除此之外如PHP、Ruby、Python等也都屬於動態語言，而C、C++、Java等語言則不屬於動態語言。
大部分動態語言都使用動態類型，但也有些不是。

**特徵**
動態語言可能包含的特徵有：eval函數、對象運行時間改變、類型推論、可變內存分配、反射和宏。

**Eval**
一些動態語言提供eval函數。這個函數接受包含這個語言寫的代碼的一個字符串或抽象語法樹並執行它。如果這個代碼表示了一個表達式，則返回它的結果值。Erik Meijer和Peter Drayton將eval提供的運行時代碼生成，同共享庫提供的動態裝載區別開來，並提醒注意在很多情況下eval只是用來實現高階函數（通過將函數作為字符串來傳遞）或解序列化。

**對象運行時間改變**
在動態語言中類型或對象系統典型的是可以改變的。這意味著可以從運行時間定義或基於現存類型或對象的mixin來生成新對象。這還可以用來稱謂變更繼承或類型樹，從而改變了現存類型系統表現的方式（特別是關於方法調用）。

**類型推論**
由於很多動態語言具有動態類型系統，基於值的內部解釋的運行時間類型推論是一種常見任務。因為值類型在各處解釋中可以變更，它經常在進行原子性運算時使用。

**可變內存分配**
靜態編程語言（可能間接的）要求開發者在編譯之前定義使用內存的大小（除非採用指針機制來解決問題）。一致於對象運行時間改變，動態語言隱含的需要基於程序個別運算而（重新）分配內存。

**反射**
反射常見於很多動態語言中，典型的涉及到分析出泛型或多態數據的類型和元數據。此外它還可以包括將程序代碼作為數據的完全求值和修改，比如Lisp提供的分析S-表達式的那種特徵。

**宏**
有限數目的動態語言提供一種叫做宏的特徵，用來組合代碼內省（檢查類、函數和關鍵字來知道它們是什麼、幹什麼、知道什麼的能力）和eval。多數當代程序員是從C或C++中知道這個術語的，在這裡它們是建造入語言的小子集中的一種靜態特徵，只有在程序的文本上進行字符串替換的能力。在動態語言中，它們提供對編譯器的內部工作的訪問，和對解釋器、虛擬機或運行時系統的完全訪問，允許定義可以優化代碼或修改語言的語法或文法的類似語言的構造。

**例子代碼**
下列代碼使用Common Lisp和它的Common Lisp對象系統（CLOS）展示語言的動態特徵，具體採用的實現是SBCL。

**代碼在運行時間算得和後期綁定**
這個例子展示函數可以在運行時間從源代碼進行修改：
 源代碼作為數據存儲在一個變量中- (defparameter *best-guess-formula* '(lambda (x) (* x x 2.5)))
*BEST-GUESS-FORMULA
 從源代碼創建一個函數並在運行時間執行，這個函數可獲得於best-guess名下- (compile 'best-guess *best-guess-formula*)
BEST-GUESS
NIL
NIL
 這個函數可以被調用- (best-guess 10.3)
265.225
 源代碼可以在運行時間改進- (setf *best-guess-formula* `(lambda (x) ,(list 'sqrt (third *best-guess-formula*))))
(LAMBDA (X) (SQRT (* X X 2.5)))
 這個函數的新版本被編譯- (compile 'best-guess *best-guess-formula*)
BEST-GUESS
NIL
NIL
 下次調用將調用新版本，這是後期綁定的特徵- (best-guess 10.3)
16.28573

**對象運行時間改變**
這個例子展示，現存的實例在它的類變更時可以被變更來包括一個新槽，還有現存的方法可以被替代為新版本：
 person類，person有一個name- (defclass person () ((name :initarg :name)))
#
 給類person的對象的一個定製的打印方法- (defmethod print-object ((p person) stream)
(print-unreadable-object (p stream :type t)
(format stream "~a" (slot-value p 'name))))
#
 一個例子person實例- (defparameter *person-1* (make-instance 'person :name "Eva Luator"))
#
 類person得到第二個槽，它從而擁有槽name和age- (defclass person () ((name :initarg :name) (age :initarg :age :initform :unknown)))
#
 更新打印這個對象的方法- (defmethod print-object ((p person) stream)
(print-unreadable-object (p stream :type t)
(format stream "~a age: ~d" (slot-value p 'name) (slot-value p 'age))))
WARNING:
redefining PRINT-OBJECT (#
#) in DEFMETHOD
#
 現存的對象已經被變更了，它有了增加的槽和新的print方法- *person-1#
 可以設置實例的新age槽- (setf (slot-value *person-1* 'age) 25)
25
 這個對象已經被更新- *person-1#

**基於實例的類的代碼在運行時間組裝**
在下列例子中，類person得到一個新超類。print方法得到重新定義，它組裝了多個方法成為有效（effective）方法。基於實際參數的類和運行時間可獲得和適用的方法，有效方法得以組裝：
 類person- (defclass person () ((name :initarg :name)))
#
 person只打印它的name- (defmethod print-object ((p person) stream)
(print-unreadable-object (p stream :type t)
(format stream "~a" (slot-value p 'name))))
#
 一個person實例- (defparameter *person-1* (make-instance 'person :name "Eva Luator"))
*PERSON-1
 顯示這個person實例- *person-1#
 現在重新定義print方法為可擴展的
 :around方法創建print方法的上下文，並且它調用call-next-method- (defmethod print-object :around ((p person) stream)
(print-unreadable-object (p stream :type t)
(call-next-method)))
#
 主要方法打印name- (defmethod print-object ((p person) stream)
(format stream "~a" (slot-value p 'name)))
WARNING:
redefining PRINT-OBJECT (#
#) in DEFMETHOD
#
 新類id-mixin提供了一個id- (defclass id-mixin () ((id :initarg :id)))
#
 :after方法只打印id槽的值- (defmethod print-object :after ((object id-mixin) stream)
(format stream " ID: ~a" (slot-value object 'id)))
#
 現在重新定義類person來包括混入的id-mixin- (defclass person (id-mixin) ((name :initarg :name)))
#
 現存實例*person-1*現在有了一個新槽並設置它為42- (setf (slot-value *person-1* 'id) 42)
42
 再次顯示這個對象，print-object函數現在有一個有效方法，它調用三個方法：:around方法、主要方法和:after方法- *person-1#

**語言**
APL
*C#（≥4.0）
*ChucK
*Clipper- CFML
*Curl
*D
*xBase
*ECMAScript
**ActionScript
**JavaScript
*Eiffel
*Erlang
*Forth
*Groovy
*Harbour (programming language)
*HyperCard/HyperTalk
*Io
*Lisp
**Scheme
**Common Lisp
**Clojure
**Dylan
**Emacs Lisp
**newLISP
**PicoLisp
*Logo
*Logtalk
*Lua
*Maude system
*MUMPS
*Oberon
*Objective-C
*Perl
*PHP
*POP-11
*Poplog
*Pike
*Prolog
*Python
*R
*REALbasic
*REBOL
*Ruby
*Scala
*Scratch
*Smalltalk
**Self
**Squeak
**Pharo
*SNOBOL
*Squirrel (programming language)
*SuperCollider
*Tcl
**XOTcl
*TeX
*VBScript
*Visual Basic 9+
*Visual FoxPro
*PowerShell
*xHarbour

**參見**
腳本語言

**引用**

**延伸閱讀**
 dead-url=no

**外部鏈接**
 dead-url=no - dead-url=no - cite speech |author-link1=Larry Wall |last1=Wall |first1=Larry |date=2007-12-06 |url=https://www.perl.com/pub/2007/12/06/soto-11.html/ |title=Programming is Hard, Let's Go Scripting... |event=State of the Onion 11 |work=Perl.com |access-date=2020-07-27 |archive-date=2017-07-28 |archive-url=https://web.archive.org/web/20170728023959/http://www.perl.com/pub/2007/12/06/soto-11.html |dead-url=no - cite web |last1=Roth |first1=Gregor |date=2007-11-20 |url=https://www.infoworld.com/article/2077792/scripting-on-the-java-platform.html |title=Scripting on the Java platform |work=JavaWorld |access-date=2020-07-27 |archive-date=2020-07-27 |archive-url=https://web.archive.org/web/20200727191214/https://www.infoworld.com/article/2077792/scripting-on-the-java-platform.html |dead-url=no - cite magazine |author-link1=John Ousterhout |last1=Ousterhout |first1=John K. |date=March 1998 |url=http://www.stanfordlibrary.us/~ouster/cgi-bin/papers/scripting.pdf |title=Scripting: Higher-Level Programming for the 21st Century |work=Computer |volume=31 |issue=3 |pages=23–30 |issn=0018-9162 |doi=10.1109/2.660187 |access-date=2020-07-27 |archive-date=2020-07-27 |archive-url=https://web.archive.org/web/20200727185732/http://www.stanfordlibrary.us/~ouster/cgi-bin/papers/scripting.pdf |dead-url=yes - cite news |date=2004-07-26 |url=https://www.activestate.com/company/press/press-releases/activestate-announces-focus-dynamic-languages/ |title=ActiveState Announces Focus on Dynamic Languages |publisher=ActiveState |access-date=2020-07-27 |archive-date=2020-07-27 |archive-url=https://web.archive.org/web/20200727223127/https://www.activestate.com/company/press/press-releases/activestate-announces-focus-dynamic-languages/ |dead-url=no 
** cite web |last1=Ascher |first1=David |date=2004-07-27  
publisher=ActiveState |archive-url=https://web.archive.org/web/20081118035341/https://www.activestate.com/Corporate/Publications/ActiveState_Dynamic_Languages.pdf |archive-date=2008-11-18
** cite web |last1=Ascher |first1=David |date=2004-07-27 |url=http://www.activestate.com/company/newsroom/whitepapers_ADL.plex |title=Dynamic Languages — ready for the next challenges, by design |department=Whitepapers |publisher=ActiveState |archive-url=https://web.archive.org/web/20081208121835/http://www.activestate.com/company/newsroom/whitepapers_ADL.plex |archive-date=2008-12-08