Макросы для генерации функций - PullRequest
0 голосов
/ 01 сентября 2018

Я пытаюсь написать несколько макросов для программирования ограничений на целые числа и, в частности, я пытаюсь раскрыть

(int-constr (x y z) 
        (< 10  
       (+
        (* x 4)
        (* y 5)
        (* z 6)))
    (> 10
       (+
        (* x 1)
        (* y 2)
        (* z 3))))

в

(let ((x (in-between 0 1))
      (y (in-between 0 1))
      (z (in-between 0 1)))
  (assert  
   (and (< 10  
           (+
            (* x 4)
            (* y 5)
            (* z 6)))
        (> 10
           (+
            (* x 1)
            (* y 2)
            (* z 3)))))
  (list x y z))

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

1 Ответ

0 голосов
/ 01 сентября 2018

Даже если придерживаться syntax-rules, этот макрос легко написать с помощью эллипсов. Вот реализация описанного вами поведения:

(define-syntax int-constr
  (syntax-rules ()
    ((_ (x ...) constr ...)
     (let ((x (in-between 0 1)) ...)
       (assert (and constr ...))
       (list x ...)))))

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

...