After reading some of the original paper by Dybvig[1],
I finally managed to get the macro right. The trick
was to use "with-syntax", which -- I have to admit
-- is still a little magical to me. But by mimicking
the way the procedure "generate-temporaries" has
been used in the Dybvig's implementation of letrec,
I came up with the following solution:

(define-syntax private+public
  (lambda (stx)
    (define (name interface)
      (define (interface-name interface)
        (match interface
          ((head . tail)
           (interface-name head))
          ((? symbol? name)
           name)))
      (datum->syntax stx (interface-name (syntax->datum interface))))
    (syntax-case stx ()
      ((_ (private ...) ((define-variant interface . body) ...))
       (with-syntax (((name ...) (map name #'(interface ...))))
         #`(begin
             (define name (and (defined? 'name) name))
             ...
             (let ()
               private ...
               (set! name
                     (let ()
                       (define-variant interface . body)
                       name))
               ...)))))))

[1] http://www.cs.indiana.edu/~dyb/pubs/tr356.pdf

Reply via email to