Как вы можете определить, является ли язык "динамическим языком"?
Я пытаюсь лучше понять, что значит для языка быть "динамичным". У меня довольно большой опыт работы с Lingo, который является языком сценариев для линейки продуктов Adobe (ранее Macromedia) Director, и мне просто интересно, можно ли считать его "динамическим языком".
То, как обрабатываются переменные и списки, кажется мне очень "динамическим".
С переменными, вы бы просто написать foo = 3
или же bar = "Hello World"
, Вы не объявляете переменную как int
или же string
- он выясняет это как есть.
Со списками вы можете просто написать что-то вроде miscCollection = [3, "Hello World", #helloWorld, ["Embedded List", "Goes Here", 3], [#phrase: "Property List goes here", #value: 3]]
, Разве это не будет похоже на tuple
?
Достаточно ли этих функций для получения статуса "динамический язык"?
Интересно, что я использую C# намного больше, а Director/Lingo - намного меньше, но, несмотря на то, что в наши дни я испытываю восторг от динамических языков, мне интересно, действительно ли я иду против зерна.
РЕДАКТИРОВАТЬ
Что касается ответа Марка Рушакова, ниже, вот попытка проанализировать, может ли Lingo квалифицироваться как "динамический", используя эту статью в Википедии:
Eval
- Линго имеетdo
а такжеvalue
ключевые слова.do
выполнит всю команду, например,do "foo = 23"
или жеdo "foo = sum(20, 3)"
,value
пытается преобразовать строку в числовое, но это больше, чем просто оператор синтаксического анализа - он может фактически преобразовать строковое представление переменной в ее число, например, предполагая,foo = 23
, заявлениеvalue("foo")
будет оценивать до 23.Функции высшего порядка - если я правильно понимаю, это то, что я бы назвал "делегатом" в C#. Насколько я знаю, Lingo не поддерживает это напрямую, хотя вы можете создать тип (называемый "родительский скрипт"), который имеет функцию и передает экземпляр типа.
Замыкания - Насколько я знаю, никакой поддержки этому нет.
Продолжение - Насколько я знаю, никакой поддержки этому нет.
Отражение - по крайней мере, в некотором смысле, да. Вы фактически создаете новые экземпляры типов, используя строку, например,
fooInstance = script("Foo").new(bar)
, Также возможно преобразовать экземпляр типа в строку, содержащую имя типа (так что вы можете сортировать имитирующие C#GetType()
функциональность). Вы также можете запросить свойства типа, не зная имен свойств (например, поиск свойства по индексу) и узнать имена свойств по индексу.Макросы. То, как в статье в Википедии описывается макрос, я так не считаю. Однако можно редактировать сценарии во время выполнения, поэтому, возможно, это имеет значение.
Таким образом, кажется, что Линго получает от 2 до 3 баллов из 6 по динамическим функциям, но я недостаточно уверен в замыканиях и продолжениях, чтобы точно знать, что Линго их не поддерживает. Я думаю, я не уверен, что сделать вывод. Комментарии приветствуются.
4 ответа
"динамическое" - это одно из тех модных слов, но оно действительно означает немного больше, чем "то, что я делаю, это круто"... оно не имеет точного определения.
Сказав это, я могу ответить на ваш вопрос о типах или, по крайней мере, попытаться объяснить разницу между типизированным и нетипизированным (что некоторые люди называют динамическими или динамически типизированными) языками лучше.
Типизированный язык проверяет, что вы никогда не будете пытаться что-то сделать с переменной, которую вы не можете сделать до запуска программы. Нетипизированный язык не выполняет эту проверку - он просто надеется на лучшее и, если в какой-то момент у него есть значение, которое не подходит для того, что ему нужно, выдает ошибку.
Это две крайности. Как и все в жизни, на практике языки лежат где-то между двумя теоретическими крайностями. Поэтому иногда трудно сказать, что язык типизирован или нетипизирован - часто все, что вы можете сказать, это что-то вроде "язык X имеет лучшую проверку типов во время компиляции, чем язык Y, потому что эти ошибки обнаруживаются в X, но не в Y:... ".
Учитывая это определение, вы можете беспокоиться о том, что (1) типизированный язык требует намного больше текста в программе (потому что вам нужно сказать, какой тип у каждого значения) и (2) что типизированный язык может ограничивать то, что вы можете делать без необходимости (потому что система типов не достаточно умна, чтобы позволить что-то, что вы видите, сработает).
Оба из них могут быть проблемы. НО они обе проблемы, которые становятся менее важными, поскольку типизированные языки становятся лучше. Например, почему есть такой код:
String s = "hello"
когда это очевидно только с
s = "hello"
что "s" должно быть строкой? Такие "умные" языки, где нет необходимости говорить, что это за типы, но они все еще проверены, часто называют "Хиндли Милнер", потому что это люди, которые первыми придумали, как это сделать. в деталях.
Поэтому, когда вы смотрите на программу, написанную для языка с системой типов Хиндли Милнера, может показаться, что у нее нет типов. Но это ошибка. До запуска программы все равно будет определено, какими должны быть все типы всех переменных, и убедитесь, что вы не можете получить никаких ошибок при попытке сделать что-то с неправильным типом (я думаю, это удивительно - это близко к своего рода искусственный интеллект...)
Это означает, что иногда единственный способ узнать, типизирован ли язык или нет, это узнать, как он реализован. Это может быть не очевидно, просто глядя на источник.
Изменить: я просто перечитал выше, и я мог бы быть немного яснее. Различие, которое я пытался провести, было между языками, которые имеют систему типов , и языками, которые не имеют. Система типов включает в себя две вещи: сами типы и логику для проверки правильности типов.
Языки, которые я называл "нетипизированными" (или динамически типизированными), имеют типы. Например, в Python (который является нетипизированным динамическим языком) все еще существует разница между String и Integer. Но у них нет лишней логики, которая проверяет программу перед ее запуском. Поэтому было бы точнее сказать, что у них есть типы, но нет системы типов.
В отличие от "типизированных" языков, как я уже сказал, проверяйте перед запуском программы, и поэтому для выполнения этой работы должны быть не только типы, но и дополнительная логика.
Тип вывода (например, ваши примеры foo = 3
а также bar = "Hello World"
) не подразумевает динамический язык. var
Ключевое слово в C# выводит тип переменной во время компиляции, и Haskell также может использовать неявную типизацию для всех переменных, даже в скомпилированных программах.
"Динамический язык программирования" - довольно свободно определенный термин, но я думаю, что если бы вам пришлось ограничить его одним определителем, это было бы отражением во время выполнения. Если вы можете сделать отражение, вы, вероятно, можете сделать другие квалификаторы, перечисленные в статье в Википедии (eval, изменение времени выполнения объекта, замыкания, макросы...).
Я ничего не знаю о языке Lingo, но я бы сказал, что вообще легче дисквалифицировать язык как динамический, чем квалифицировать язык. Может ли Линго сделать какие-либо / все квалификаторы в статье Википедии? Если нет, то это, вероятно, просто не динамично. Если это может сделать что-то, то это, вероятно, по крайней мере, "достаточно динамично".
Когда люди говорят о "динамическом" языке программирования, они обычно имеют в виду систему динамических типов. Лучшее определение того, что такое система динамических типов (а что нет), которую я когда-либо читал, - это отличная статья Криса Смита " Что нужно знать перед тем, как обсуждать системы типов".
Прочитав эту статью, я думаю, у вас должен быть ответ на вопрос о том, квалифицируется ли какой-либо язык как статически или динамически типизированный.
Я хотел бы показать, что Lingo - это динамический язык.
Я сделал LingoF - функциональную среду программирования для Lingo. Этот Framework полностью написан на Lingo, без xtra, не используются низкоуровневые компоненты, поэтому было бы невозможно разработать такой каркас, если бы язык не был динамическим.
Учитывая эту структуру, вот моя оценка для Lingo как Динамического языка:
1 - Eval - Линго имеет do
а также value
ключевые слова. Плюс вы можете скомпилировать скрипт во время исполнения. Смотрите функцию LingoF "Выражения Lingo".
2 - Функции высшего порядка - LingoF показывает, насколько возможно широко использовать функции высшего порядка в Lingo.
3 - Замыкания - снова LingoF показывает, как можно работать с замыканиями в Линго.
4 - Продолжение - помощники синтаксиса LingoF определяются с помощью методов продолжения. Можно написать функции в стиле продолжения продолжения. Проверьте это (взято из модуля LingoF):
on public_factorialCPS_2
on fac me, n,k
x = LingoF().var()
if ( n = 0 ) then return k [1]
else return me.factorialCPS[$(#-,n,1) ] [ LingoF().fun(x) [ k [ $(#*,n,x) ] ] ]
end
5 - Отражение - уже ответили да и я согласен. Например, менеджер модулей LingoF реализован с использованием функций отражения Lingo, упомянутых DanM.
6 - Макросы - мне придется больше исследовать в этой области. Поскольку Director поддерживает связанные скрипты (скрипты, хранящиеся во внешних текстовых файлах), можно реализовать некоторые макросы. Может быть, менеджер макросов может перехватывать некоторые события, такие как startMovie
(расширить их) и stopMovie
(сжать их снова). Еще одна возможность - использовать поля в качестве скриптов и расширять их в членах скриптов, я уверен, что это будет работать нормально.
Таким образом, моя оценка составляет 5-6 из 6 по динамическим характеристикам.