0

I'm trying to write some macros for constraint programming on integers and specifically I'm trying to expand

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

into

(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))

When using syntax-rules recursively, I can create nested let at the beginning, but I think I lose the possibility of calling the list of arguments at the end. Is there any way to do it?

1 Answers1

1

Even just sticking to syntax-rules, this macro is easy to write by using ellipses. Here’s an implementation of the behavior you describe:

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

Since ellipses can be used to repeat forms containing pattern variables, not just repeat plain pattern variables on their own, this macro is quite declarative, and it’s both simple to read and write.

Alexis King
  • 43,109
  • 15
  • 131
  • 205