что происходит, когда я устанавливаю переменную параметра в defun?(Emacs) - PullRequest
1 голос
/ 26 января 2011
(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. Что происходит? Это мой вопрос.

Для некоторых из вас, кто пришел сюда, погуглив и задаваясь вопросом, как заставить make-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.

1 Ответ

7 голосов
/ 26 января 2011

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

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

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

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

Затем интерпретатор применяет функциюк списку аргументов, который включает в себя локальные привязки между его аргументами к значениям, переданным в .В этом случае выполняется локальная привязка между символом num и значением 0.Затем тело функции вычисляется в этой среде.

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

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

...