Время привязки свободных переменных указанных терминов в схеме

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

Например, когда я пишу

(define q 'a)
(define a 42)
(eval q)

он возвращает 42. Таким образом, я делаю вывод, что время привязки находится во время выполнения. Но в этом случае, почему этот код не работает

(let ((q 'a))
  (let ((a 42))
    (eval q)
  )
)

и возвращается

unbound variable:  a

Может кто-нибудь объяснить мне, какова модель времени привязки цитируемых терминов (например, сопоставима ли она с MetaOCaml? (Я так не думаю)) и в чем разница между define и let?

2 ответа

Схема имеет лексическую дисциплину, а не динамическую дисциплину.

Ваш верхний уровень define определения ведут себя так, как будто создают привязку в лексической среде верхнего уровня.

Второй фрагмент кода фактически создает две лексические среды, одна вложенная в другую. Так где (не "когда") q связан, a все еще не связан. Но реальный вопрос в том, какая среда используется eval?

Ваша реализация ведет себя так, как будто она использует среду определения или среду верхнего уровня, но определенно не текущую лексическую среду, для оценки символа 'a, который является значением q переменная. Переменная q имеет четкую обязательную лексическую среду, созданную его let форма - но при чем здесь символ 'aОбязательный проживать? Откуда нам знать?

Подробности должны быть в документации.

Прежде всего, символ в кавычках - это такая же переменная, как и строка с теми же последовательностями символов, что и переменная в языке синтаксиса Си, таком как Javascript. У них нет ничего общего, так как они живут в разных мирах.

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

(eval '(let ((tmp (list q q))) 
          tmp)) 

q должен быть глобальным, но tmp является лексической переменной

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

Переменные связаны во время выполнения. Реализации свободны для оптимизации и постоянного сворачивания, если эта оптимизация не нарушает отчет.

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

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