![]() |
|
![]() ![]() ![]() |
|
GreenTea22 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 7 Регистрация: 6.9.2009 Репутация: нет Всего: нет |
В книге Practical Common Lisp в конце главы про макросы
(http://gigamonkeys.com/book/macros-defining-your-own.html) есть пример макроса, который обеспечивает расчет аргументов макроса 1 раз в заданном порядке " Another classic macro-writing macro is once-only, which is used to generate code that evaluates certain macro arguments once only and in a particular order. Using once-only, you could write do-primes almost as simply as the original leaky version, like this: (defmacro do-primes ((var start end) &body body) (once-only (start end) `(do ((,var (next-prime ,start) (next-prime (1+ ,var)))) ((> ,var ,end)) ,@body))) However, the implementation of once-only is a bit too involved for a blow-by-blow explanation, as it relies on multiple levels of backquoting and unquoting. If you really want to sharpen your macro chops, you can try to figure out how it works. It looks like this: (defmacro once-only ((&rest names) &body body) (let ((gensyms (loop for n in names collect (gensym)))) `(let (,@(loop for g in gensyms collect `(,g (gensym)))) `(let (,,@(loop for g in gensyms for n in names collect ``(,,g ,,n))) ,(let (,@(loop for n in names for g in gensyms collect `(,n ,g))) ,@body))))) " Я только начинаю изучать лисп и такой страшный макрос просто шокировал. Потом все таки с горем пополам разобрался как он работает. А теперь ВОПРОС к уважаемым знатокам лиспа. В чем недостаток моей реализации этого макроса? (defmacro my-once-only ((&rest names) &body body) `(let (,@(loop for n in names collect `(,n (eval ,n)))) ,@body)) |
|||
|
||||
adejneka |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 105 Регистрация: 8.7.2005 Где: Москва, Россия Репутация: 9 Всего: 11 |
DO-PRIMES с Вашей версией ONCE-ONLY производит вычисление аргументов START и END на этапе компиляции кода, использующего DO-PRIMES. Это работает только в том случае, когда аргументы - константные выражения без побочных эффектов, например, (DO-PRIMES (PRIME 11 99) ...). Если же значения этих аргументов должны определяться на этапе исполнения, особенно, если они имеют побочные эффекты, например, (DO-PRIMES (PRIME (AREF LOWER I) (PRINT (AREF UPPER (INCF I))) ...), то Ваш макрос не сработает:
|
|||
|
||||
![]() ![]() ![]() |
Правила форума LISP | |
|
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Void. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | LISP | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |