Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Правильно определить макрос в Сommon Lisp, проблема с аргументами 
:(
    Опции темы
ferbolg
Дата 8.11.2010, 22:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 1
Регистрация: 8.11.2010

Репутация: нет
Всего: нет



Доброго времени суток!Задача: определить макрос do-loop <task1>...<taskn> until <test>. Вызов должен выглядеть например так:
Код

(do-loop (princ 1) until (nil))


Главный момент: слово until должно фигурировать в вызове. Встретил такой вариант решения:
 
Код

(defmacro do-loop (body &until test) 

`( do ()

  ((,@test))

  ,body)

 )



Но что в данном случае обозначает запись &until ? until ведь не некое специальное слово в CL...
PM MAIL   Вверх
VH_
Дата 10.11.2010, 09:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 182
Регистрация: 31.10.2006

Репутация: 10
Всего: 11



Пожалуй, необходимость присутствия символа until в вызове макро здесь связана с тем, что <по заданию> необходимо обеспечить выполнение нескольких (то есть заранее неизвестно скольких) задач (у Вас они обозначены <task1>...<taskn>). То есть макро следует «научить» обрабатывать переменное число аргументов. Известно, что в CommonLISP для указания на список аргументов произвольной длины используется параметр &REST. Определение макро, следовательно, будет выглядеть
Код
(defmacro do-loop (&rest args) ...)

В теле макро <вероятно> следует анализировать список args на предмет того, есть ли в нем вообще символ until и считать все аргументы до символа until подлежащими выполнению задачами <task1>...<taskn>, а первый после символа until аргумент - тестовым выражением <test>.
PM MAIL   Вверх
VH_
Дата 11.11.2010, 14:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 182
Регистрация: 31.10.2006

Репутация: 10
Всего: 11



Код

(defmacro DO-LOOP (&rest Args)
 (if Args
  ((lambda (fdef seq)
    (funcall fdef fdef seq))
   (lambda (fname L &optional acc)
    (if L
     (if (equal (car L) 'UNTIL)
      (cons 'PROGN
       (append acc
        (list (cons 'DO (cons nil (cons (cdr L) acc))))))
      (funcall fname fname (cdr L) (append acc (list (car L)))))))
   Args)))

PM MAIL   Вверх
k0rvin
Дата 21.11.2010, 17:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 442
Регистрация: 24.1.2010

Репутация: нет
Всего: 5



Код

CL-USER 1 > (defmacro do-loop (&body body)
              (loop :for b :on body
                    :for e :in body
                    :when (eq e 'until)
                    :do (return-from do-loop
                          `(do () ,(rest b) ,@xs))
                    :collect e :into xs)
              (error "No ~s expression in ~s" 'until 'do-loop))
DO-LOOP

CL-USER 2 > (let ((i 0))
              (do-loop
                (princ "Iteration #")
                (princ i)
                (terpri)
                (incf i)
                until
                (> i 10)))
Iteration #0
Iteration #1
Iteration #2
Iteration #3
Iteration #4
Iteration #5
Iteration #6
Iteration #7
Iteration #8
Iteration #9
Iteration #10
NIL

CL-USER 3 > 


Это сообщение отредактировал(а) k0rvin - 21.11.2010, 17:07


--------------------
“Object-oriented design is the roman numerals of computing.” — Rob Pike
All software sucks
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума LISP
Void
  • Пожалуйста, создавайте темы с содержательными названиями.
  • Lisp — это целое семейство языков. Всегда указывайте в теме используемый диалект (Common Lisp, Scheme и т.д.).
  • Уважаемые учащиеся, здесь всегда рады помочь Вам, но не делать за Вас вашу работу. У вас гораздо больше шансов получить помощь, если Вы приложите усилия и поделитесь с нами проблемами и результатами. В противном случае добро пожаловать в раздел Центр Помощи.
  • Получив ответ на интересующий Вас вопрос, не забудьте пометить его как решённый.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Void.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | LISP | Следующая тема »


 




[ Время генерации скрипта: 0.0416 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.