Как семантика "лексическая и специальная переменная" реализуется вообще под капотом?

CLtL2 прояснил различие между областью применения и объемом. В отношении лексических и специальных переменных я полагаю, что лексические переменные "лексически ограничены с неопределенной степенью", а специальные переменные "неопределенно ограничены динамическим расширением".

Мой вопрос: как семантика "лексической и специальной переменной" реализуется в целом? Под "в целом" я подразумеваю, что достаточно общей идеи. Учитывая долгую историю Lisp, для реализации этих базовых концепций должны быть применены многочисленные оптимизации.

Чтобы начать обсуждение, я рискну предположить ниже.

Все начинается со среды. Среда - это последовательность кадров, причем каждый кадр представляет собой таблицу, которая отображает имена в местах (значение которых можно извлечь и сохранить); каждое такое отображение - это привязка имени к месту. Кадры связаны вложенными отношениями; имя во внутренней рамке может скрывать то же имя во внешней рамке. Кроме того, привязки в Common Lisp по умолчанию являются лексическими, если declare-d /declaim-ed /proclaimдолжен быть особенным.

Существует два аспекта семантики: поиск имени и создание новой привязки.

  • Создайте новую привязку. lambda выражения, let/let*, labels/flet, macroletи макросы, использующие их, создают привязки. Лексическая привязка создается путем создания нового фрейма и наличия текущей лексической среды, которая будет окружением нового фрейма. Специальная привязка (которая должна быть явно объявлена) перемещает новое место на вершину стека, созданного для имени в текущем пакете (стек может быть расположен, возможно, с помощью хеш-таблицы по именам) - стек используется для реализации динамический экстент, так что при выходе из конструирующей формы привязка может быть разобрана путем выталкивания стека (вопрос заключается в том, как это обеспечить, возможно, с помощью чего-то вроде unwind-protect под капотом?).

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

1 ответ

Я думаю, что этот вопрос, вероятно, будет перенесен на http://programmers.stackexchange.com/, но есть и другие вопросы о Stackru, в которых даются ответы на некоторые из этих вопросов, хотя ни один из найденных мной до сих пор не является точной копией. Посмотри на:

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

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