В информатике , язык динамического программирования является классом языков программирования высокого уровня , который на время выполнения выполняет многие тип поведения общего программирования , что статические языки программирования выполнять во время компиляции . Это поведение может включать расширение программы путем добавления нового кода , расширения объектов и определений или изменения системы типов.. Хотя подобное поведение можно эмулировать практически на любом языке, с разной степенью сложности, сложности и затрат на производительность, динамические языки предоставляют прямые инструменты для их использования. Многие из этих функций были впервые реализованы как собственные функции в языке программирования Lisp .
Большинство динамических языков также имеют динамическую типизацию , но не все. Динамические языки часто (но не всегда) называют языками сценариев , хотя этот термин в самом узком смысле относится к языкам, специфичным для данной среды выполнения.
Выполнение
Eval
Некоторые динамические языки предлагают функцию eval . Эта функция принимает строковый параметр, содержащий код на языке, и выполняет его. Если этот код обозначает выражение, возвращается результирующее значение. Однако Эрик Мейер и Питер Дрейтон предлагают программистам «использовать eval как замену беднякам для функций высшего порядка ». [1]
Изменение среды выполнения объекта
Тип или объектную систему обычно можно изменить во время выполнения на динамическом языке. Это может означать создание новых объектов из определения среды выполнения или на основе миксинов существующих типов или объектов. Это также может относиться к изменению наследования или дерева типов и, таким образом, к изменению поведения существующих типов (особенно в отношении вызова методов ).
Отражение
Отражение распространено во многих динамических языках и обычно включает анализ типов и метаданных общих или полиморфных данных. Однако он может также включать в себя полную оценку и модификацию кода программы как данных, например, функции, которые Lisp предоставляет при анализе S-выражений .
Макросы
Ограниченное количество языков динамического программирования предоставляет функции, которые сочетают в себе интроспекцию кода (возможность изучать классы, функции и ключевые слова, чтобы знать, что они собой представляют, что они делают и что они знают) и eval в функции, называемой макросами . Большинство современных программистов, знакомых с термином « макрос» , сталкивались с ним в C или C ++ , где они представляют собой статическую функцию, встроенную в небольшое подмножество языка и допускающие только строковые подстановки в тексте программы. Однако в динамических языках они обеспечивают доступ к внутренней работе компилятора и полный доступ к интерпретатору, виртуальной машине или среде выполнения, позволяя определять языковые конструкции, которые могут оптимизировать код или изменять синтаксис или грамматику язык.
Ассемблер , C , C ++ , ранняя версия Java и Fortran обычно не попадают в эту категорию. [ требуется разъяснение ]
Пример кода
В следующих примерах показаны динамические функции, использующие язык Common Lisp и его объектную систему Common Lisp (CLOS).
Вычисление кода во время выполнения и позднее связывание
В примере показано, как функция может быть изменена во время выполнения из вычисленного исходного кода.
; исходный код хранится как данные в переменной CL-USER > ( defparameter * best-guess-formula * ' ( lambda ( x ) ( * x x 2.5 ))) * BEST-GUESS-FORMULA *; функция создается из кода и компилируется во время выполнения, функция доступна под именем best-guess CL-USER > ( compile 'best-guess * best-guess-formula * ) # 15 40600152F4>.; функцию можно назвать CL-USER > ( предположение 10.3 ) 265.225; исходный код может быть улучшен во время выполнения CL-USER > ( setf * best-guess-formula * ` ( lambda ( x ) , ( list 'sqrt ( third * best-guess-formula * )))) ( LAMBDA ( X ) ( КОРЕНЬ ( * Х Х 2,5 ))); компилируется новая версия функции CL-USER > ( compile 'best-guess * best-guess-formula * ) # 16 406000085C>; следующий вызов вызовет новую функцию, функцию позднего связывания CL-USER > ( предположение 10.3 ) 16.28573
Изменение среды выполнения объекта
В этом примере показано, как существующий экземпляр можно изменить, чтобы включить новый слот при изменении его класса, и что существующий метод можно заменить новой версией.
; человек класс. У человека есть имя. CL-USER > ( defclass person () (( name : initarg : name ))) # < ЛИЦО СТАНДАРТНОГО КЛАССА 4020081FB3>; настраиваемый метод печати для объектов класса person CL-USER > ( defmethod print-object (( p person ) stream ) ( print-unreadable-object ( p stream : type t ) ( format stream "~ a" ( slot-value) р имя» )))) # <СТАНДАРТ-МЕТОД ПЕЧАТЬ-ОБЪЕКТ NIL ( ЛицО Т ) 4020066E5B>; один пример экземпляра человека CL-USER > ( setf * person-1 * ( make-instance 'person : name "Eva Luator" )) # < PERSON Eva Luator>; классный человек получает второй слот. Затем у него есть имя и возраст слота. CL-USER > ( defclass person () (( name : initarg : name ) ( age : initarg : age : initform : unknown ))) # < ЛИЦО СТАНДАРТНОГО КЛАССА 4220333E23>; обновление метода для печати объекта CL-USER > ( defmethod print-object (( p person ) stream ) ( print-unreadable-object ( p stream : type t ) ( format stream "~ a age: ~" ( значение слота) р 'имя ) ( слот-значение р ' возраст )))) # <СТАНДАРТ-МЕТОД ПЕЧАТЬ-ОБЪЕКТ NIL ( ЛицО Т ) 402022ADE3>; существующий объект теперь изменен, у него есть дополнительный слот и новый метод печати CL-USER > * person-1 * # < PERSON Eva Luator age: UNKNOWN>; мы можем установить новый возрастной интервал для экземпляра CL-USER > ( setf ( slot-value * person-1 * 'age ) 25 ) 25; объект обновлен CL-USER > * person-1 * # < PERSON Eva Luator возраст: 25>
Сборка кода во время выполнения на основе класса экземпляров
В следующем примере человек класса получает новый суперкласс. Метод печати переопределяется таким образом, что он объединяет несколько методов в эффективный метод. Эффективный метод собирается на основе класса аргумента и доступных и применимых методов во время выполнения.
; класс люди CL-USER > ( DEFCLASS люди () (( имя : initarg : название ))) # <СТАНДАРТ-КЛАСС PERSON 4220333E23>; человек просто печатает свое имя CL-USER > ( defmethod print-object (( p person ) stream ) ( print-unreadable-object ( p stream : type t ) ( форматный поток "~ a" (имя слота p ' ) ))) # <СТАНДАРТ-МЕТОД ПЕЧАТЬ-ОБЪЕКТ NIL ( ЛицО Т ) 40200605AB>; экземпляр человека CL-USER > ( defparameter * person-1 * ( make-instance 'person : name "Eva Luator" )) * PERSON-1 *; отображение экземпляра человека CL-USER > * person-1 * # < PERSON Eva Luator>; теперь переопределяем метод печати, чтобы он был расширяемым ; метод around создает контекст для метода печати и вызывает следующий метод CL-USER > ( defmethod print-object : around (( p person ) stream ) ( print-unreadable-object ( p stream : type t ) ( call- next-method ))) # < ОБЪЕКТ ПЕЧАТИ СТАНДАРТНЫМ МЕТОДОМ ( : ВОКРУГ ) ( ЛИЦО T ) 4020263743>; основной метод печатает имя CL-USER > ( defmethod print-object (( p person ) stream ) ( формат потока "~ a" ( значение слота p 'name ))) # PRINT-OBJECT NIL ( PERSON Т ) 40202646BB>; новый класс id-mixin предоставляет идентификатор CL-USER > ( defclass id-mixin () (( id : initarg : id ))) # ID-MIXIN 422034A7AB>; метод печати просто печатает значение идентификатора слота CL-USER > ( defmethod print-object : after (( object id-mixin ) stream ) ( формат потока "ID: ~ a" ( id объекта значения слота ))) # < ОБЪЕКТ ПЕЧАТИ СТАНДАРТНЫМ МЕТОДОМ ( : ПОСЛЕ ) ( ID-MIXIN T ) 4020278E33> ; Теперь мы переопределять класс человека включить Mixin Ид подмешать CL-USER 241 > ( DEFCLASS лицо ( ID-подмешать ) (( имя : initarg : название ))) # <СТАНДАРТ-КЛАСС PERSON 4220333E23>; существующий экземпляр * person-1 * теперь имеет новый слот, и мы устанавливаем его на 42 CL-USER 242 > ( setf ( slot-value * person-1 * 'id ) 42 ) 42); отображение объекта снова. Функция объекта печати теперь имеет эффективный метод, который вызывает три метода: метод обхода, основной метод и метод после. CL-USER 243 > * person-1 * # < PERSON Eva Luator ID: 42>
Примеры
Популярные языки динамического программирования включают JavaScript , Python , Ruby , PHP , Lua и Perl . Следующие языки обычно считаются динамическими языками:
- ActionScript
- BeanShell [2]
- C # (с использованием Reflection)
- Clojure
- CobolScript
- Язык разметки ColdFusion
- Common Lisp и большинство других Lisp
- Дилан
- E
- Эликсир
- Erlang
- Четвертый
- Гамбас
- GDScript
- Groovy [3]
- Java (с использованием Reflection)
- JavaScript
- Юлия
- Lua
- MATLAB / Octave
- Цель-C
- Perl
- PHP
- PowerShell
- Пролог
- Python
- р
- Раку
- Ребол
- Рубин
- Болтовня
- Суперколлайдер
- Tcl
- VBScript
- Язык Wolfram Language
Смотрите также
- Сравнение языков программирования
- Привязка имени
- Архитектура фон Неймана
Рекомендации
- ^ Мейер, Эрик и Питер Дрейтон (2005), Статический ввод текста там, где это возможно, динамический набор текста, когда это необходимо: Конец холодной войны между языками программирования , Корпорация Microsoft , CiteSeerX 10.1.1.69.5966
- ^ Глава 24. Поддержка динамического языка . Static.springsource.org. Проверено 17 июля 2013.
- ^ < «Архивная копия» . Архивировано из оригинала на 2014-03-02 . Проверено 2 марта 2014 .CS1 maint: заархивированная копия как заголовок ( ссылка )
дальнейшее чтение
- Тратт, Лоуренс (2009). Динамически типизированные языки . Достижения в области компьютеров. 77 . С. 149–184. DOI : 10.1016 / s0065-2458 (09) 01205-4 . ISBN 9780123748126.
Внешние ссылки
(Многие используют термин «языки сценариев».)
- Прешельт, Лутц (18 августа 2002 г.). «Хороши ли языки сценариев? Проверка Perl, Python, Rexx и Tcl на C, C ++ и Java» (PDF) . Достижения в области компьютеров . 57 : 205–270. DOI : 10.1016 / S0065-2458 (03) 57005-X . ISSN 0065-2458 . Проверено 27 июля 2020 .
- Безроуков, Николай (2013). «Слегка скептический взгляд на языки сценариев» . Softpanorama (2,1 изд.) . Проверено 27 июля 2020 .
- Уолл, Ларри (6 декабря 2007 г.). Программирование - это сложно, давайте писать сценарии ... (Речь). Состояние лука 11. Perl.com . Проверено 27 июля 2020 .
- Рот, Грегор (20 ноября 2007 г.). «Скриптинг на платформе Java» . JavaWorld . Проверено 27 июля 2020 .
- Остерхаут, Джон К. (март 1998 г.). «Сценарии: программирование высокого уровня для 21 века» (PDF) . Компьютер . Vol. 31 нет. 3. С. 23–30. DOI : 10.1109 / 2.660187 . ISSN 0018-9162 . Проверено 27 июля 2020 .
- «ActiveState объявляет о фокусе на динамических языках» . ActiveState . 26 июля 2004 . Проверено 27 июля 2020 .
- Ашер, Дэвид (27 июля 2004 г.). «Динамические языки - по дизайну готовы к новым вызовам» (PDF) . Белые бумаги. ActiveState . Архивировано из оригинального (PDF) 18 ноября 2008 года.
- Ашер, Дэвид (27 июля 2004 г.). «Динамические языки - по дизайну готовы к следующим вызовам» . Белые бумаги. ActiveState . Архивировано из оригинала на 2008-12-08.