Особенности списков аргументов
Наша простая функция-пример, (lambda (a b c) (+ a b c)), определяет три переменные аргументов, поэтому ее вызов должен содержать три аргумента: если вы попытаетесь вызвать ее с только двумя аргументами или четырьмя аргументами, вы получите ошибку wrong-number-of-arguments (см. Ошибки).
Часто удобно написать функцию, которая позволяет опускать некоторые аргументы. Например, функция substring принимает три аргумента — строку, начальный и конечный индексы — но третий аргумент по умолчанию равен длине строки length, если вы его опустите. Также удобно для некоторых функций принимать неопределенное количество аргументов, как это делают функции list и +.
Чтобы указать необязательные аргументы, которые можно опустить при вызове функции, просто добавьте ключевое слово &optional перед необязательными аргументами. Чтобы указать список из нуля или более дополнительных аргументов, добавьте ключевое слово &rest перед последним аргументом.
Таким образом, полная синтаксическая конструкция для списка аргументов следующая:
(required-vars… [&optional [optional-vars…]] [&rest rest-var])
В квадратных скобках указано, что &optional и &rest пункты, а также переменные, следующие за ними, необязательны.
Для вызова функции требуется один фактический аргумент для каждой из required-vars. Может быть ноль или более фактических аргументов для optional-vars, и не может быть никаких фактических аргументов, превышающих это число, если только список лямбда не использует &rest. В этом случае может быть любое количество дополнительных фактических аргументов.
Если фактические аргументы для необязательных и остаточных переменных опущены, то они всегда по умолчанию равны nil. Функция не может отличить явный аргумент nil от опущенного аргумента. Однако тело функции свободно рассматривает nil как сокращение для некоторого другого осмысленного значения. Именно это делает substring; nil в качестве третьего аргумента для substring означает использование длины предоставленной строки.
Примечание по Common Lisp: Common Lisp позволяет функции указать, какое значение по умолчанию использовать, когда необязательный аргумент опущен; Emacs Lisp всегда использует
nil. Emacs Lisp не поддерживает переменныеsupplied-p, которые сообщают о том, был ли аргумент явно передан.
Например, список аргументов, который выглядит так:
(a b &optional c d &rest e)
привязывает a и b к первым двум фактическим аргументам, которые являются обязательными. Если предоставлены еще один или два аргумента, c и d привязываются к ним соответственно; все аргументы после первых четырех собираются в список, и e привязывается к этому списку. Таким образом, если аргументов только два, c, d и e являются nil; если два или три аргумента, d и e являются nil; если четыре аргумента или меньше, e является nil. Обратите внимание, что ровно пять аргументов с явным аргументом nil для e приведут к тому, что этот аргумент nil будет передан как список с одним элементом, (nil), как и любое другое отдельное значение для e.
Нельзя иметь обязательные аргументы после необязательных — это не имеет смысла. Чтобы понять, почему это так, предположим, что c в примере было необязательным, а d — обязательным. Предположим, что предоставлены три фактических аргумента; для какой переменной будет третьим аргумент? Будет ли он использоваться для c, или для d? Можно аргументировать оба варианта. Аналогично, не имеет смысла иметь какие-либо дополнительные аргументы (обязательные или необязательные) после аргумента &rest.
Вот некоторые примеры списков аргументов и правильных вызовов:
(funcall (lambda (n) (1+ n)) ; One required: 1) ; requires exactly one argument. ⇒ 2 (funcall (lambda (n &optional n1) ; One required and one optional: (if n1 (+ n n1) (1+ n))) ; 1 or 2 arguments. 1 2) ⇒ 3 (funcall (lambda (n &rest ns) ; One required and one rest: (+ n (apply '+ ns))) ; 1 or more arguments. 1 2 3 4 5) ⇒ 15
Copyright © 1990-1996, 1998-2022 Free Software Foundation, Inc.
Licensed under the GNU GPL license.
https://www.gnu.org/software/emacs/manual/html_node/elisp/Argument-List.html