LISP: параметры ключевого слова, предоставленные-p

#lisp #common-lisp

#lisp #common-lisp

Вопрос:

На данный момент я работаю над «Практическим Common Lisp» от Питера Сейбела.

В главе «Практическое применение: простая база данных» (http://www.&i&amonkeys.com/book/practical-a-simple-database.html) Сейбел объясняет параметры ключевого слова и использование предоставленного параметра на следующем примере:

 (defun foo (amp;key a (b 20) (c 30 c-p)) (list a b c c-p))
  

Результаты:

 (foo :a 1 :b 2 :c 3)  ==&&t; (1 2 3 T)
(foo :c 3 :b 2 :a 1)  ==&&t; (1 2 3 T)
(foo :a 1 :c 3)       ==&&t; (1 20 3 T)
(foo)                 ==&&t; (NIL 20 30 NIL)
  

Итак, если я использую amp;key в начале моего списка параметров, у меня есть возможность использовать список из 3 имен параметров, значения по умолчанию и третьего, если параметр был предоставлен или нет. ОК.
Но, глядя на код в приведенном выше примере:

 (list a b c c-p)
  

Откуда интерпретатор lisp знает, что c-p является моим «предоставленным параметром»?

Ответ №1:

Давайте переиндентируем функцию foo:

 (defun foo (amp;key a
                 (b 20)
                 (c 30 c-p))
   (list a b c c-p))
  

Если вы сделаете отступ таким образом, вы увидите, что функция имеет три параметра ключевого слова: a, b и c. Они доступны в теле функции.

Для параметра ключевого слова c объявлена переменная c-p, которая будет равна T или NIL в зависимости от того, был ли передан c при вызове foo.

Параметр ключевого слова обычно может быть объявлен как один из следующих параметров:

  1. как имя одной переменной
  2. список с именем переменной и значением по умолчанию
  3. список имени переменной, значения по умолчанию и переменной, который покажет, был ли передан параметр или нет, когда вызывается функция

Предоставленный-p особенно интересен, когда нужно посмотреть, является ли значение результатом вызова или значением по умолчанию:

 (defun make-my-array (size amp;key (init-value nil init-value-supplied-p))
   (if init-value-supplied-p
       (make-array size :initial-element init-value)
       (make-array size)))
  

Теперь пользователь может инициализировать элементы до нуля:

 (make-my-array 10 :init-value nil)
  

Здесь значение по умолчанию и предоставленное значение могут быть равны нулю, но нам нужно внести изменения. Переменная init-value-предоставлено-p позволяет увидеть, является ли нулевое значение переменной init-value значением по умолчанию или результатом вызова функции.

Ответ №2:

Трудно сказать, о чем вы спрашиваете. c-p привязано к T или NIL , в зависимости от того, c указано ли это в качестве параметра. Затем эта привязка становится доступной для тела функции.

Комментарии:

1. Аааа, понял 🙂 c-p просто добавляется в список, как a, b и c, и не является «предоставленным параметром» для «список был установлен / отменен». Требуется некоторое время, чтобы привыкнуть к синтаксису, хотя он действительно прост. 🙂 Спасибо!