Take the following code:
(require racket/match) (define-syntax-rule (methods* [(method-name method-args ...) body ...] ... fallback) (let ((method-name (lambda (method-args ...) body ...)) ...) (define all-methods (list (cons 'method-name method-name) ...)) (define method-dispatch (make-keyword-procedure (lambda (kw-args kw-vals method . args) (match (assq method all-methods) [(cons _name found-method) found-method #;(keyword-apply found-method kw-args kw-vals args)] [#f (keyword-apply fallback kw-args kw-vals method args)])))) method-dispatch)) (define no-such-method (make-keyword-procedure (lambda (kw-vals kw-args method . args) (error "No such method" method)))) (define-syntax-rule (methods method-defns ...) (methods* method-defns ... no-such-method))
This is kind of a kluge, I know. But you get the idea. Let over
lambda, because we're going to be reusing these procedures over and over
again across multiple calls.
Now let's say I instantiate this like:
(define my-methods (methods [(double x) (* x x)]))
> my-methods #<procedure:...tor-lib/methods.rkt:130:7>
That's the line where method-dispatch is defined, inside the macro.
But what I really want is for the annotation on the procedure to be
where my-methods is defined.... not pointing back inside the macro.
I have no idea how to do this. Thoughts?