#lang racket
(require (for-syntax racket/base))
(provide formals define-formal formal? n/f-list? n/f-pair? ?eq? ?eqv? ?equal? ?= ?> ?< ?>= ?<=)
(define formals (make-parameter '()))
(define-syntax (define-formal stx)
(syntax-case stx ()
[(_ id) (let* ([str (symbol->string (syntax-e #'id))]
[str? (string->symbol (string-append str "?"))])
(with-syntax ([id? (datum->syntax #'id str? #'id)])
#'(begin
(define-match-expander id
(syntax-rules ()
[(id x (... ...)) (list (quote id) x (... ...))])
(syntax-id-rules (id)
[id (λ x (cons (quote id) x))]
[(id x (... ...)) (list (quote id) x (... ...))]))
(define (id? x) (and (pair? x)
(list? x)
(eq? (car x) (quote id))))
(formals (cons id? (formals))))))]
[(_ ids ...) #'(begin (define-formal ids) ...)]))
(define (formal? x)
(ormap (λ(f)(f x)) (formals)))
(define (n/f-list? x)
(and (list? x)
(not (formal? x))))
(define (n/f-pair? x)
(and (pair? x)
(not (formal? x))))
(define-match-expander ?eq?
(syntax-rules ()
[(?eq? x) (? (λ(y)(eq? x y)))]))
(define-match-expander ?eqv?
(syntax-rules ()
[(?eqv? x) (? (λ(y)(eqv? x y)))]))
(define-match-expander ?equal?
(syntax-rules ()
[(?equal? x) (? (λ(y)(equal? x y)))]))
(define-match-expander ?=
(syntax-rules ()
[(?= x) (? (λ(y)(= x y)))]))
(define-match-expander ?<
(syntax-rules ()
[(?< x) (? (λ(y)(< x y)))]))
(define-match-expander ?>
(syntax-rules ()
[(?> x) (? (λ(y)(> x y)))]))
(define-match-expander ?<=
(syntax-rules ()
[(?<= x) (? (λ(y)(<= x y)))]))
(define-match-expander ?>=
(syntax-rules ()
[(?>= x) (? (λ(y)(>= x y)))]))