Помимо Логотипа и Lisp Emacs, что другими чистыми являются динамично ограниченные по объему языки?

Если у Вас будет статический hashmap, и Вы добавляете данные к нему, то... данные никогда не будут исчезать, и у Вас есть утечка - в случае, если Вам больше не нужны данные. При необходимости в данных это не утечка, а огромная груда бродящей вокруг памяти.

12
задан 4 revs, 3 users 67% 5 February 2015 в 21:36
поделиться

4 ответа

Языки с динамической областью видимости намного проще реализовать. Чтобы получить доступ к переменным, которых нет в текущей записи активации / кадре стека, достаточно просто перейти по ссылкам управления. В этом случае статические / лексические ссылки доступа не нужны, что делает фреймы стека меньше.

Динамические переменные могут быть «непредсказуемыми» во время выполнения, потому что нужно знать, в каком порядке фактические фреймы стека должны знать, какая переменная будет использоваться. Эту информацию нельзя получить, просто глядя на статическую структуру кода. Можно довольно легко попасть в ловушку, если фактический график вызовов программы нелегко предсказать во время реализации. Вот почему большинство языков сегодня имеют статическую область видимости (однако большинство систем исключений являются динамическими, поскольку это наиболее практично).

Однако в некоторых случаях очень полезны переменные с динамической областью видимости. Например, при перенаправлении вывода вы можете с помощью динамических переменных установить стандартный вывод для локального кода и всего кода, вызываемого оттуда.

(let ((*standard-output* *some-other-stream*))
 (stuff))

В этом примере common-lisp (от Seibel) стандартный вывод привязан к другому потоку на время действия let-формы (внутри закрывающих скобок). Когда выполнение покидает let, оно возвращается к тому, что было до этого. См. http://gigamonkeys.com/book/variables.html отличную бесплатную книгу Питера Зейбелса «Практический Common Lisp» для хорошего обсуждения. По собственным словам Сейбелса:

Динамические привязки делают глобальные переменные более управляемыми, но это « Важно отметить, что они по-прежнему позволяют действовать на расстоянии. Привязка глобальной переменной имеет два удаленных эффекта - она ​​может изменить поведение нижележащего кода, а также открывает возможность того, что последующий код присвоит новое значение привязке, установленной выше в стеке. Вы должны использовать динамические переменные только тогда, когда вам нужно воспользоваться одной или обеими этими характеристиками.

9
ответ дан 2 December 2019 в 05:54
поделиться

Ну, есть множество веб-сайтов, на которых обсуждаются плюсы и минусы, поэтому я не собираюсь туда идти.

Один интересный язык, который имеет некоторые функции, которые слегка напоминают динамическую область видимости, - это XSLT; Хотя шаблоны и переменные XSLT и т.п. имеют лексическую область видимости, XSLT, конечно же, полностью посвящен XML - и текущая позиция в дереве xml имеет «динамическую область видимости» в том смысле, что контекстный узел является глобальным и, следовательно, выражения XPath не оцениваются. в соответствии с лексической областью XSLT, но в соответствии с его динамической оценкой.

3
ответ дан 2 December 2019 в 05:54
поделиться

Mathematica - это еще один язык с динамической областью видимости с помощью конструкции Block . На самом деле это очень полезно при работе с формулами. Это позволяет вам писать такие вещи, как

 In[1]:= expr = a*t^2 + b*t+ c;

 In[2]:= Block[{a = 1, b = -1, c = 2}, Table[expr, {t, 5}]]
 Out[2]= {2, 4, 8, 14, 22}

, которые вообще не работали бы, если бы такие переменные, как a и t , имели лексическую область видимости. Это особенно хорошо работает с системой переписывания правил Mathematica, которая, среди прочего, оставляет переменные неоцененными (как символические выражения), если для них нет существующего определения.

Mathematica может имитировать лексическую область видимости с помощью ] Module , но на самом деле это переписывает выражение в терминах нового, предположительно уникального символа (вы можете вызвать конфликты, если предскажете, каким будет следующий уникальный символ, что в большинстве случаев легко). Это означает, что

Module[{x = 4}, 
  Table[x * t, {t, 5}]]

будет преобразован во что-то вроде этого:

Block[{x$134 = 4},
  Table[x$134 * t, {t, 5}]

Emacs Lisp в одной из своих библиотек имеет конструкцию (на самом деле макрос Lisp) под названием lexical-let , которая выполняет точно такой же трюк. подделать лексическую область видимости.

При компиляции языка реальная лексическая область видимости дает преимущества в производительности, которых нельзя добиться с поддельными лексиками ELisp или Mathematica, поскольку вам нужно некоторое сопоставление между динамической переменной и ее текущим значением, что означает выполнение поиск (через хеш-таблицу или список свойств или что-то еще) и дополнительные уровни косвенного обращения.

РЕДАКТИРОВАТЬ : Если у вас есть только лексические переменные, вы можете имитировать динамическую область видимости, сохраняя исходное значение глобальной лексической переменной при входе в область видимости и гарантируя восстановление старого значения при выходе из области видимости. Для этого вам понадобится что-то вроде блока Lisp UNWIND-PROTECT или finally . Я видел, как это делалось и с деструкторами C ++, в основном в качестве упражнения.

8
ответ дан 2 December 2019 в 05:54
поделиться

Динамическую область видимости легче реализовать с помощью интерпретаторов. Большинство ранних интерпретаторов Лиспа использовали динамическую область видимости. Спустя несколько лет было обнаружено, что лексическая область видимости имеет преимущество, но сначала она была реализована в основном в компиляторах Lisp. Появилось несколько реализаций, реализующих динамическую область видимости в интерпретируемом коде и лексическую область видимости в скомпилированном коде. Некоторые предоставляют специальные языковые конструкции для замыканий. Диалекты Lisp, такие как Scheme и Common Lisp, тогда требовали, чтобы не было разницы между интерпретируемым и скомпилированным кодом, и, таким образом, интерпретируемые реализации на основе также должны были реализовать лексическую область видимости.

Ранние реализации Smalltalk реализовали динамическую область видимости. Все виды реализаций диалекта Лиспа реализовали динамическую область видимости (Interlisp, UCI Lisp, Lisp Machine Lisp, MacLisp, ...).

Почти все новые диалекты Lisp за последние 20 лет используют лексическую область видимости по умолчанию или даже исключительно. В нескольких публикациях подробно описано, как реализовать Lisp с лексической областью видимости, поэтому нет оправдания тому, чтобы не использовать лексическую область видимости.

3
ответ дан 2 December 2019 в 05:54
поделиться