Вопрос: Функция, которая просто возвращает свой аргумент?


В Common Lisp есть функция в стандартной библиотеке, которая просто возвращает заданный параметр (т. Е. Не манипулирует данными)? Эта функция будет эквивалентна (lambda (x) x), Я хочу использовать его как значение по умолчанию для необязательного параметра. Например, такая функция заменит (lambda (x) x) в:

(defun some-function (value &optional (transformation (lambda (x) x)))
  (other-function (funcall transformation value))

7


источник


Ответы:


Взгляни на identity:

функция   ИДЕНТИЧНОСТЬ

Синтаксис:

идентичность   объект  &Правая стрелка; объект

Аргументы и значения:

объект -an объект ,

Описание:

Возвращает свой аргумент объект ,

BTW, стандарт ANSI CL определяет почти тысячу символов. Вы не можете научиться им всю ночь. Кроме того, Lisp - это язык с богатой историей, поэтому, если вы хотите что-то «общего назначения», есть вероятность, что либо язык предоставляет, либо какую-либо (полу) стандартную библиотеку.

Спрашивай! Не изобретайте велосипед.


10



Ответ sds  описывает идентичность  функция, которая соответствует спецификации, которую вы просили: это в значительной степени просто (lambda (x) x), Однако стоит отметить, что в такой функции, как

(defun some-function (value &optional (transformation (lambda (x) x)))
  (other-function (funcall transformation value))

Это мог бы  быть более идиоматичным, чтобы описать ваши преобразование  как ключ , и пусть ноль  что никакая ключевая функция не должна применяться к значению. Такое поведение присутствует в многие  Общие функции Лиспа. Например, член  принимает ключевой аргумент, который применяется к каждому элементу последовательности для получения значения, которое сравнивается с поисковым элементом:

CL-USER> (member nil '(1 2 3 4 nil 5 6 7 8))
(NIL 5 6 7 8)
CL-USER> (member nil '(1 2 3 4 nil 5 6 7 8) :key 'oddp)
(2 3 4 NIL 5 6 7 8)

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

CL-USER> (member nil '(1 2 3 4 nil 5 6 7 8))
(NIL 5 6 7 8)
CL-USER> (member nil '(1 2 3 4 nil 5 6 7 8) :key 'identity)
(NIL 5 6 7 8)

Однако значение по умолчанию не   идентичность , но ноль , HyperSpec для член  говорит о ключе:

key - обозначение для функции одного аргумента или ноль ,

Это указано в 17.2.1. Удовлетворение теста с двумя аргументами  в котором говорится, что:

Если предоставлен аргумент ключа::, это обозначение для функции   один аргумент, который должен быть вызван с каждым Ei в качестве аргумента, и   объект Zi, который будет использоваться для сравнения. (Если нет: ключевой аргумент, Zi   Ei.)

Если вы хотите принять этот тип соглашения, то ваш код будет чем-то вроде

(defun some-function (value &optional transformation)
  (other-function (if (null transformation) value (funcall transformation value))))

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


10



Чтобы немного расширить вопрос, #'identity вернет свой аргумент, если у вас есть один аргумент. #'list вернет несколько аргументов в список и #'values будут возвращать их в виде нескольких значений, они выполняют одну и ту же цель, но имеют очень разные API.


1