Здравствуйте!
Мне кажется, обнаружил некоторую неточность в описании лексического замыкания:
http://lisp.ystok.ru/fp/lisp/1_58.html#_h62“Определение f порождает объект-функцию, называемую лексическим замыканием. Оно включает не только исполняемый код, но и часть вычислительного окружения со
значениями всех свободных переменных, встречающихся в теле определения.”
Однако, если я правильно понял, лексическое замыкание содержит не сами значения свободных переменных, а их связывания. Вот пример:
Код:
(let ((pair
(let ((x 0))
(cons (lambda (a) (setq x a))
(lambda () x)))))
(setf (symbol-function 'setit) (car pair))
(setf (symbol-function 'getit) (cdr pair)))
(getit)
(setit 1)
(getit)
И ещё такой вопрос: до меня никак не доходит в чём прелесть концепции динамического связывания?
Вы упоминали на одной из лекций, что это одна из уникальных черт Лиспа, которая в других языках отсутствует, но в чём же заключается её практическое удобство?
Тем более, что в Лиспе существует механизм необязательны и ключевых параметров, при том, что значением по умолчанию необязательного параметра может быть результат вычислениях произвольной формы, а не как в C# - только литералы, значениях, которых известны на момент компиляции. Не могу придумать какой-то пример, в котором ключевые\необязательные параметры не были бы более безопасным решением.
У меня сложилось впечатление, что переменные с динамическим связыванием представляют собой чуть менее вредную разновидность глобальных переменных. Однако использование глобальных переменных считается плохим стилем в любом из известных мне языков/парадигм, поэтому очень хочется увидеть как-нибудь конкретный пример.