Macro de raqueta para definir automáticamente las funciones dada una lista

Quiero generar automáticamente un montón de funciones de prueba de una lista. La ventaja es que puedo cambiar la lista (por ejemplo, leyendo en una tabla de datos CSV) y el programa generará automáticamente diferentes pruebas en la próxima ejecución del programa.

Por ejemplo, digamos que estoy tratando de identificaroxianiones en una cadena que contiene unafórmula química.

Mi lista puede ser algo como:

(define *oxyanion-tests*
  ;           name         cation
  (list (list "aluminate"  "Al")
        (list "borate"     "B")
        (list "gallate"    "Ga")
        (list "germanate"  "Ge")
        (list "phosphate"  "P")
        (list "sulfate"    "S")
        (list "silicate"   "Si")
        (list "titanate"   "Ti")
        (list "vanadate"   "V")
        (list "stannate"   "Sn")
        (list "carbonate"  "C")
        (list "molybdate"  "Mo")
        (list "tungstate"  "W")))

Estoy razonablemente seguro de que la fórmula química contiene uno de estosoxianiones si hay un catión seguido de un oxígeno entre paréntesis (por ejemplo, "(C O3)"), o si al catión le siguen 2 o más oxígenos (por ejemplo, "C O3"). Tenga en cuenta que esto no es perfecto, ya que se perderán los aniones de hipoclorito (por ejemplo, "Cl O"), pero es lo suficientemente bueno para mi aplicación.

(define ((*ate? elem) s-formula)
  (or (regexp-match? (regexp (string-append "\\(" elem "[0-9.]* O[0-9.]*\\)")) s-formula)
      (regexp-match? (regexp (string-append "(^| )" elem "[0-9.]* O[2-9][0-9.]*")) s-formula)))

Creo que necesito una macro para hacer esto, pero realmente no entiendo cómo funcionan al leer la documentación. Estoy pidiendo aquí para que tenga un buen ejemplo para ver que me sea inmediatamente útil.

Esto es lo que creo que debería ser la macro, pero no funciona y realmente no tengo un modelo mental para descubrir cómo solucionarlo.

(require (for-syntax racket))
(define-syntax-rule (define-all/ate? oxyanion-tests)
  (for ([test oxyanion-tests])
    (match test
      [(list name cation) (syntax->datum (syntax (define ((string->symbol (string-append name "?")) s-formula)
                                    ((*ate? cation) s-formula))))])))

Gracias por cualquier orientación que me puedas dar!

PD Aquí hay algunas pruebas que deben pasar:

(define-all/ate? *oxyanion-tests*)
(module+ test
  (require rackunit)
  (check-true (borate? "B O3"))
  (check-true (carbonate? "C O3"))
  (check-true (silicate? "Si O4")))