[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

method definition syntax vs. wrapping lambda



I'm using a hack for keeping procedure expressions around, inspired by 
a suggestion from Matthew on this list a while back:

  (module keep-source mzscheme
    (define ht (make-hash-table 'weak))

    (define (set-procedure-expression! v src)
      (hash-table-put! ht v src)
      v)

    (define (procedure-expression v)
      (hash-table-get ht v))  

    (define-syntax (wrapper-lambda stx)
      (syntax-case stx ()
        [(_ . rest)
         (syntax (set-procedure-expression! (lambda . rest) '(lambda . rest)))]))

    (define-syntax (wrapper-define stx)
      (syntax-case stx ()
        [(_ (id . formals) . body)
         (syntax (define id (wrapper-lambda formals . body)))]
        [(_ . rest)
         (syntax (define . rest))]))

    (provide procedure-expression
             (rename wrapper-lambda lambda)
             (rename wrapper-define define)))

  (require keep-source)
  (require-for-syntax keep-source)

This works great for the most part, but it turns out to interfere with 
the syntax for defining methods in classes (using v200 class.ss):

  > (define foo
      (class object%
        (public bar)
        (define (bar) 'baz)
        (super-make-object)))
  fred.scm:56:8: class*/names: bad form for method definition at: (set-procedure-expression! (lambda () (quote baz)) (quote (lambda () (quote baz)))) in: (class*/names (this super-instantiate super-make-object) object% () (public bar) (define (bar) (q...

As the manual says, "Method definition is syntactically restricted to
certain procedure forms", and this isn't one of them.  Even if I change
wrapper-lambda to use a let it doesn't work:

  fred.scm:56:8: class*/names: bad form for method definition at: (let-values (((proc) (lambda () (quote baz)))) (set-procedure-expression! proc (quote (lambda () ... in: (class*/names (this super-instantiate super-make-object) object% () (public bar) (define (bar) (q...

Is there a way to make this work?  I don't think I actually need to
keep the source for methods, since there doesn't appear to be any way
to retrieve the method closures from a class anyway, so if there were
some way to avoid having lambdas get wrapped in class definitions that 
would be fine.

--dougo@ccs.neu.edu