Common Lisp: Работа с параметрами & rest - PullRequest
14 голосов
/ 10 марта 2009

Может кто-нибудь сказать мне, как работать с параметрами, хранящимися в значении, указанном & rest.

Я много читал, и кажется, что авторы знают, как перечислить все параметры, как это.

(defun test (a &rest b) b)

Это приятно видеть, но не очень полезно.

Лучшее, что я нашел на данный момент, это использовать first, second и т. Д., Чтобы получить искомый параметр.

(defun test (a &rest b)
    (first b))

Я заметил, что этот метод перестает работать с десятым параметром, но спецификация (из того, что я прочитал) поддерживает минимум 50. Даже если шансы малы, что я буду использовать 50 параметров, я бы хотел знать, как получить к ним доступ.

Спасибо

Ответы [ 5 ]

8 голосов
/ 10 марта 2009

Параметр отдыха - это просто список. Вы можете справиться с этим, используя обычные операции со списком.

(defun test (a &rest b))
  (dolist (s b)
    (when (> s 1)
      (print s)
      (do-something-else b)))
6 голосов
/ 10 марта 2009

На самом деле функция полезна. Вам нужно только попробовать.

CL-USER 1 > (defun test (a &rest b) b)
TEST

CL-USER 2 > (test 1 2 3 4)
(2 3 4)

Итак, вы видите, что B - это просто список аргументов. Таким образом, применяются все операции со списком и последовательностями. В этом нет ничего волшебного. Существуют функции для доступа к элементу NTH, функции для удаления элементов и т. Д.

В Common Lisp HyperSpec перечислены соответствующие функции:

14. Словарь Conses

17. Словарь последовательностей

Для основного учебника по Лиспу, посмотрите книгу Турецкого:

Common Lisp: Нежное введение в символические вычисления

Книга доступна для скачивания в формате PDF и Postscript. Он учит основному Common Lisp.

6 голосов
/ 10 марта 2009

Функции доступа FIRST, SECOND и т. Д. Являются «просто» служебными функциями поверх CAR / CDR или NTH. Итак, я полагаю, что ответ на ваш конкретный вопрос - «используйте NTH или ELT» (или создайте свои собственные специальные функции-предшественники).

Если хотите, вы можете определить ОДИННАДЦАТУ как:

(определение одиннадцатого (список) (десятый список))

Однако я нахожу, что я в основном использую аргументы & REST, когда есть 0 или более вещей, с которыми я хочу что-то сделать, не особо заботясь о конкретной позиции данного аргумента в списке & REST. Это обычно влечет за собой использование LOOP, DO или DOLIST, чтобы пройти через аргументы и что-то сделать с каждым из них; семейство MAP или (иногда) УМЕНЬШЕНИЕ.

3 голосов
/ 10 марта 2009

Вы также можете использовать destructuring-bind:

(defun my-function (&rest arguments)
  (destructuring-bind (a b &rest c) arguments
    (format nil "~A,~A followed with ~A" a b c)))

CL-USER> (my-function 1 2 "Give" 'me "more" 'arguments!!)
==> "1,2 followed with (Give ME more ARGUMENTS!!)"
0 голосов
/ 29 сентября 2010

У меня просто рекурсивная итерация, чтобы пройти их все, я думаю, что dolist лучше, но мне нравится использовать старомодный способ

...