Замыкания и динамический охват?

Я думаю, что понимаю, почему существует опасность в том, что допускается замыкание в языке с использованием динамического объема. То есть кажется, что вы сможете закрыть переменную OK, но при попытке прочитать ее вы получите только значение в верхней части глобального стека. Это может быть опасно, если другие функции используют то же имя в промежуточный период.

Я пропустил некоторые другие тонкости?

2 ответа

Решение

Да, это основная проблема. Термин "закрытие" сокращенно означает "лексическое закрытие", что по определению охватывает его лексическую сферу. Я бы назвал вещи в динамически ограниченном языке чем-то другим, например, LAMBDA, Лямбды совершенно безопасны на динамически ограниченном языке, если вы не пытаетесь их вернуть.

(Для интересного мысленного эксперимента сравните проблему возврата лямбды с динамической областью в Emacs Lisp с проблемой возврата ссылки на переменную, выделенную в стеке, в C, и выясните, как и то, и другое невозможно в Scheme.)

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

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

"Закрытие" означает просто вызываемый объект, который содержит как код, так и среду, которая обеспечивает привязки для свободных переменных в этом коде. Обычно это лексическая среда, но нет технической причины, по которой она не может быть динамичной.

Хитрость заключается в том, чтобы закрыть код над средой, а не с конкретными значениями. Это то, что сделал Lisp 1.5, а также то, что сделал MACLisp для "нисходящих funargs".

Вы можете увидеть, как Lisp 1.5 сделал это, прочитав руководство по Lisp 1.5 на http://www.softwarepreservation.org/projects/LISP/book

Обратите особое внимание в Приложении B на то, как eval обрабатывает FUNCTION и как применять обрабатывает FUNARG.

Вы можете получить базовый вид программирования с использованием динамических замыканий с http://c2.com/cgi/wiki?DynamicClosure

Вы можете получить подробное введение в вопросы реализации с ftp://publications.ai.mit.edu/ai-publications/pdf/AIM-199.pdf

Современные языки с динамической областью действия обычно используют поверхностное связывание, где текущее значение каждой переменной хранится в одном глобальном местоположении, а вызовы функций сохраняют старые значения в стеке. Один из способов реализации динамических замыканий с мелкой привязкой описан по адресу http://www.pipeline.com/~hbaker1/ShallowBinding.html

Другие вопросы по тегам