2011-01-26 2 views
1
(defun make-it-5 (num) 
    (setq num 5)) 
(setq a 0) 
(make-it-5 a) 
;; now a is still 0, not 5. 

В приведенном выше коде кажется, что нет (setq a 5) и (setq 0 5). Если (setq a 5) произошло, то a изменилось бы на 5, но a все равно 0. Если (setq 0 5) произошло, произошла ошибка Lisp. Что происходит? Это мой вопрос.Что происходит, когда я устанавливаю переменную параметра в defun? (Emacs)

Для некоторых из вас, кто попал сюда прибегая к помощи и интересно, как сделать макияж-It-5 работы как его имя предположить, один путь

(defmacro make-it-7 (num) ; defmacro instead of defun 
    `(setq ,num 7)) 
(setq a 0) 
(make-it-7 a) 
;; now a is 7. 

Другой:

(defun make-it-plus (num-var) 
    (set num-var (+ 1 (symbol-value num-var))) ; `set' instead of `setq' 
) 
(setq a 0) 
(make-it-plus 'a) ; 'a instead of a 
;; now a is 1. 
+0

Вопрос немного запутанный. Две альтернативы, которые вы предоставляете, требуют более подробного понимания lisp (emacs-lisp). Я предполагаю, что вы не понимаете, как они работают ... –

ответ

7

короткий ответ заключается в том, что (setq num 5)changes the binding fornum, что является связыванием, локальным с функцией make-it-5.

A неисправность следует. Хорошо убедиться, что вы знакомы с понятием evaluation.

Когда оценивается (make-it-5 a), интерпретатор ищет функцию в первом элементе выражения. В этом случае первым элементом является символ (make-it-5 - это означает, что это named function), поэтому он выглядит в function cell символа. Примечание: этот поиск может повториться, см. Symbol Function Indirection.

Остальные элементы выражения оцениваются для нахождения значений. В этом случае есть только один символ (a), и поэтому интерпретатор возвращает the contents of its value cell, то есть 0.

Затем интерпретатор применяет функцию к списку аргументов, которая включает в себя создание local bindings between its arguments to the values passed in. В этом случае производится local binding между символом num и значением 0. Затем тело функции оценивается в этой среде.

Тело - это всего лишь одно выражение, которое является «вызовом» для setq. Я помещаю «вызов» в кавычки, потому что setq является special form и не оценивает его первый аргумент, но ищет символ и устанавливает most local existing binding, что является связыванием, созданным внутри функции make-it-5.

Итак, вы меняете привязку для символа num, который является локальным для функции make-it-5.

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