If you simply want the source location to be the macro call site, one
approach is finding where the source location currently is (in this case,
it’s the lambda inside make-keyword-procedure). Then, you simply need to
thread syntax/loc through macros to put the source location there.

Here’s an example:

#lang racket

(require racket/match
         syntax/parse/define)

(define-syntax-parse-rule
  (methods*
   [(method-name method-args ...) body ...] ...
   fallback)

  #:with the-proc
  (syntax/loc this-syntax
    (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)])))

  (let ((method-name
         (lambda (method-args ...)
           body ...)) ...)
    (define all-methods (list (cons 'method-name method-name) ...))
    (define method-dispatch
      (make-keyword-procedure the-proc))
    method-dispatch))

(define no-such-method
  (make-keyword-procedure
   (lambda (kw-vals kw-args method . args)
     (error "No such method" method))))

(define-syntax-parse-rule (methods method-defns ...)
  #:with out
  (syntax/loc this-syntax
    (methods* method-defns ... no-such-method))
  out)

(define my-methods
  (methods
   [(double x)
    (* x x)]))

my-methods ;=> #<procedure:foo.rkt:42:2>

Also note that there’s procedure-rename
<https://docs.racket-lang.org/reference/procedures.html#%28def._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._procedure-rename%29%29>
and syntax-local-name
<https://docs.racket-lang.org/reference/stxtrans.html#%28def._%28%28quote._~23~25kernel%29._syntax-local-name%29%29>
which you might want to use instead:

#lang racket

(require racket/match
         syntax/parse/define)

(define-syntax-parse-rule
  (methods*
   [(method-name method-args ...) body ...] ...
   fallback)

  #:with the-name (syntax-local-name)

  (let ((method-name
         (lambda (method-args ...)
           body ...)) ...)
    (define all-methods (list (cons 'method-name method-name) ...))
    (define method-dispatch
      (procedure-rename
       (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)])))
       'the-name))
    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))

(define my-methods
  (methods
   [(double x)
    (* x x)]))

my-methods ;=> #<procedure:my-methods>



On Mon, Nov 29, 2021 at 12:18 PM Christine Lemmer-Webber <
[email protected]> wrote:

> Take the following code:
>
> #+BEGIN_SRC racket
> (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))
> #+END_SRC
>
> 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:
>
> #+BEGIN_SRC racket
>   (define my-methods
>     (methods
>      [(double x)
>       (* x x)]))
> #+END_SRC
>
> > 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?
>
> --
> You received this message because you are subscribed to the Google Groups
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/racket-users/87sfveu34u.fsf%40dustycloud.org
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CADcuegsTy9T%3Drkxcmg99qdPPSUaUbP%3D%3Duz8wFu-aS4OgEG4wQg%40mail.gmail.com.

Reply via email to