private/term.ss
(module term mzscheme
  (require "matcher.ss")
  (provide term term-let)
  
  (define-syntax (term orig-stx)
    (define (rewrite stx)
      (let loop ([stx stx])
        (syntax-case stx (unquote unquote-splicing in-hole)
          [(unquote x)
           (with-syntax ([x-rewrite (loop (syntax x))])
             (syntax (unsyntax x-rewrite)))]
          [(unquote . x)
           (raise-syntax-error 'term "malformed unquote" orig-stx stx)]
          [(unquote-splicing x)
           (with-syntax ([x-rewrite (loop (syntax x))])
             (syntax (unsyntax-splicing x-rewrite)))]
          [(unquote-splicing . x)
           (raise-syntax-error 'term "malformed unquote splicing" orig-stx stx)]
          [(in-hole id body)
           (and (identifier? (syntax id))
                (identifier? (syntax hole)))
           (syntax (unsyntax (plug (term id) (term body))))]
          [(in-hole . x)
           (raise-syntax-error 'term "malformed in-hole" orig-stx stx)]
          [(x ...)
           (with-syntax ([(x-rewrite ...) (map loop (syntax->list (syntax (x ...))))])
             (syntax (x-rewrite ...)))]
          [_ stx])))

    (syntax-case orig-stx ()
      [(_ arg)
       (with-syntax ([rewritten (rewrite (syntax arg))])
         (syntax (syntax-object->datum (quasisyntax rewritten))))]))
  
  (define-syntax (term-let stx)
    (syntax-case stx ()
      [(_ ([x rhs] ...) body1 body2 ...)
       (syntax
        (with-syntax ([x rhs] ...)
          (begin body1 body2 ...)))]
      [(_ x)
       (raise-syntax-error 'term-let "expected at least one body" stx)]))
#|  
  (define (test stx exp)
    (unless (equal? (eval stx) exp)
      (error 'test "~s" (syntax-object->datum stx))))
  
  (test (quote-syntax (term 1)) 1)
  (test (quote-syntax (term (1 2))) (list 1 2))
  (test (quote-syntax (term (1 ,(+ 1 1)))) (list 1 2))
  (test (quote-syntax (term-let ([x 1]) (term (x x)))) (list 1 1))
  (test (quote-syntax (term-let ([(x ...) (list 1 2 3)]) (term ((y x) ...)))) '((y 1) (y 2) (y 3)))
|#
)