Для этого есть как минимум 3 "Стиля".
1: каждый многоточие в кавычках
Soegaard уже ответил , что вы можете заменить каждый ...
в теле с (... ...)
, так что его интерпретируют как буквальный многоточие, принадлежащее внутреннему макросу, а не как «мета», принадлежащий внешнему макросу:
(define-syntax-rule (greet name)
(define-syntax-rule (name args (... ...))
(printf "hello ~a~n" (list args (... ...)))))
Преимущества: гибкийВы можете свободно смешивать буквальные (... ...)
и мета ...
эллипсы внутри тела
Недостатки: выглядит странно, если вы не видели (... ...)
до
2: цитирование на эллипсисеопределение всего внутреннего макроса
Однако, размещение (... <something>)
вокруг чего-либо не ограничивается только ...
.Если вы поместите туда целый шаблон, любые ...
s в этом шаблоне также будут "заключены в кавычки", обработаны как литералы вместо мета, таким же образом:
(define-syntax-rule (greet name)
(...
(define-syntax-rule (name args ...)
(printf "hello ~a~n" (list args ...)))))
Преимущества: Если у вас есть дажебольшая глубина вложения вам не понадобится ((... ...) (... ...))
, как в случае с вариантом 1, вам просто потребуется (... <something-containing (... <something>)>)
Недостатки: жесткие, если вы положите (... <something>)
вокруг чего-то, что вы никогда не сможете использоватьмета-эллипсис внутри этого чего-то.Вы не можете свободно смешивать литералы и мета-эллипсы, как в стиле 1 или 3.
3: Создание переменной-шаблона для представления буквального эллипса
Вот еще один способ, который я нахожуменее запутанно, но требует использования define-simple-macro
вместо define-syntax-rule
, так что вы можете связать новые переменные шаблона, используя #:with
.
(require syntax/parse/define)
(define-simple-macro (<name> <arguments>)
#:with <pattern-variable> <expression>
<body-expression>)
Вы можете использовать с #:with
, чтобы связать ooo
переменная шаблона к буквальному эллипсу: #:with ooo (quote-syntax ...)
(require syntax/parse/define)
(define-simple-macro (greet name)
#:with ooo (quote-syntax ...)
(define-syntax-rule (name args ooo)
(printf "hello ~a~n" (list args ooo))))
Преимущества: Гибкость, вы можете свободно смешивать буквальные ooo
и мета ...
эллипсы внутри тела.Для меня это выглядит менее запутанно, чем (... ...)
или ((... ...) (... ...))
.
Недостатки: для более глубокого вложения вам может понадобиться несколько #:with
-определений, по одному на каждом мета-уровне.