2016-06-25 3 views
2

Я понимаю, как работает этот код:Dynamic Variable Закрытие в Common Lisp (SBCL)

(defvar *nums* '(2 3 5)) 

(defun print-nums() 
    (format t "~a~%" *nums*)) 

(print-nums) 
-> (2 3 5) 
-> NIL 

Я даже понимаю, как новое значение динамически связанная переменная *nums* передается print-nums в этом коде:

(let ((*nums* '(1 2 3))) 
    (print-nums)) 
-> (1 2 3) 
-> NIL 

Но почему код ниже не работает одинаково?

(defvar *my-nums-f* (let ((*nums* '(1 2 3))) 
         #'(lambda() (format t "~a~%" *nums*)))) 

(funcall *my-nums-f*) 
-> (2 3 5) 
-> NIL 

Является ли понятие замыкания неприменимым к динамически связанным переменным, или я делаю что-то неправильно? Если я ошибочно понял концепцию закрытия, может кто-нибудь, пожалуйста, объясните мне это?

+2

Вы можете посмотреть [этот вопрос] (http://stackoverflow.com/questions/463463/dynamic-and-lexical-variables-in-common-lisp) (динамические и лексические переменные в Common Lisp) и относительные ответы, в частности [ответ Райнера Йосвига] (http://stackoverflow.com/a/2386051/2382734). – Renzo

ответ

3
(defvar *my-nums-f* (let ((*nums* '(1 2 3))) 
         #'(lambda() (format t "~a~%" *nums*)))) 

Здесь мы устанавливаем *my-nums-f* в результате

(let ((*nums* '(1 2 3))) 
    #'(lambda() (format t "~a~%" *nums*))) 

Эта форма начинается с динамически привязки *nums* к '(1 2 3), затем возвращение #'(lambda() (format t "~a~%" *nums*)), который является функцией. В конце мы сбрасываем *nums* обратно в '(2 3 5).

(funcall *my-nums-f*) 

Здесь мы вызываем функцию, хранящуюся в *my-nums-f*, которая (lambda() (format t "~a~%" *nums*)). Эта функция принимает текущее значение *nums*, которое составляет '(2 3 5).

-> (2 3 5) 
-> NIL 

Вы, кажется, ожидать, что lambda каким-то образом встраивает текущие значения всех переменных, используемых в теле функции, которые на самом деле привело бы к (format t "~a~%" '(1 2 3)) в этой точке.

Но это не так, как это работает: функция относится к самой переменной, а не к шапшоту значения переменной. Вот почему функция видит то, что текущее значение *nums* в то время, когда оно вызывается.

Смежные вопросы