Из Википедии, бесплатной энциклопедии
Перейти к навигации Перейти к поиску

В информатике , язык динамического программирования является классом языков программирования высокого уровня , который на время выполнения выполняет многие тип поведения общего программирования , что статические языки программирования выполнять во время компиляции . Это поведение может включать расширение программы путем добавления нового кода , расширения объектов и определений или изменения системы типов.. Хотя подобное поведение можно эмулировать практически на любом языке, с разной степенью сложности, сложности и затрат на производительность, динамические языки предоставляют прямые инструменты для их использования. Многие из этих функций были впервые реализованы как встроенные функции в языке программирования 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 * ) # <Function  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 * ) # <Function  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- следующий метод ))) # <СТАНДАРТ-мЕТОД  ПЕЧАТЬ-ОБЪЕКТ  ( : ВОКРУГ )  ( ЛицО  Т )  4020263743>; основной метод печатает имя CL-USER  >  ( defmethod  print-object  (( p  person )  stream )  ( формат  потока  "~ a"  ( значение слота  p  'name ))) # <STANDARD-METHOD  PRINT-OBJECT  NIL  ( PERSON  Т )  40202646BB>; новый класс id-mixin предоставляет идентификатор CL-USER  >  ( defclass  id-mixin  ()  (( id  : initarg  : id ))) # <STANDARD-CLASS  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

См. Также [ править ]

  • Сравнение языков программирования
  • Привязка имени
  • Архитектура фон Неймана

Ссылки [ править ]

  1. ^ Мейер, Эрик и Питер Дрейтон (2005), Статический ввод текста там, где это возможно, динамический набор текста, когда это необходимо: Конец холодной войны между языками программирования , Корпорация Microsoft , CiteSeerX  10.1.1.69.5966
  2. ^ Глава 24. Поддержка динамического языка . Static.springsource.org. Проверено 17 июля 2013.
  3. ^ < "Архивная копия" . Архивировано из оригинала на 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.