[racket] identifier-binding source-id vs. nominal-source-id

From: Greg Hendershott (greghendershott at gmail.com)
Date: Tue Jul 22 16:42:57 EDT 2014

p.s. I guess the tl'dr version of all that would be:

Given an identifier symbol from a source file, is there a reliable way
to find the name used in its definition?  Even following an
arbitrarily long series of contract-out and/or rename-out provides?

It doesn't seem that identifier-binding, alone, can do this. Is there
some other way?

IIUC DrRacket doesn't attempt to do this; if the definition is in
another file, the command is "Open Defining File" (but it doesn't take
you to the definition site within the file).  Maybe that's because
it's not easy to do, or perhaps not feasible generally?


On Tue, Jul 22, 2014 at 3:50 PM, Greg Hendershott
<greghendershott at gmail.com> wrote:
> So for racket-mode I have a visit-definition feature. It takes you to
> the definition of the symbol at point.
>
> I'm using identifier-binding to find the file and name, then I
> read-syntax the file and use syntax-case* to find the identifier, and
> use its syntax srcloc.
>
> The only issue I'm experiencing is what seems to be inconsistency (for
> my purposes) in what identifier-binding reports. Code below.
> Paraphrase:
>
> For a plain provide, source-id = nominal-source-id. Great.
>
> For a rename-out, the original definition name is source-id, and
> nominal-source-id is the rename. Great.
>
> For a define/contract, plus plain provide, same thing.
>
> So far it seems like source-id is the definition name. Cool!
>
> For (provide (contract-out)) --- bzzzzzt.  Now source-id is the name
> of the wrapped thing (e.g. 'provide/contract-id-pc.9), and
> nominal-source-id is the original definition name.  Huh?? This seems
> backwards.
>
> And worst of all is (provide (contract-out rename old new contract))
> -- both a contract and a rename. In this case source-id is the
> contract wrapper, nominal-source-id is the rename, and the original
> definition name is... absent.  (Well, I have it -- maybe -- from the
> user's symbol at point in the Emacs buffer.)
>
> I have a sad.
>
> I suppose I could try all 3 possibilities -- source-id,
> nominal-source-id, and the symbol at point from the Emacs buffer --
> until one (or none) succeeds. Is that my least-worst option?
>
>
> -=-=-=-=-=-=-=-
>
> ;;; provide.rkt
> #lang racket
>
> (define (f)
>   0)
> (provide f)
>
> (define (-r)
>   0)
> (provide (rename-out [-r r]))
>
> (define/contract (dc)
>   (-> any)
>   0)
> (provide dc)
>
> (define (pc)
>   0)
> (provide (contract-out [pc (-> any)]))
>
> (define (-pcr)
>   0)
> (provide (contract-out [rename -pcr pcr (-> any)]))
>
> ;;; some-other-file.rkt
> #lang racket
> (require "provide.rkt")
> (pretty-print
>  (for/list ([sym '(f r dc pc pcr)])
>    (match (identifier-binding (namespace-symbol->identifier sym))
>      [(list source-mpi source-id
>             nominal-source-mpi nominal-source-id
>             source-phase import-phase nominal-export-phase)
>       (list sym "source" source-id "nominal" nominal-source-id)])))
>
> ;; ==>
> ;; '((f "source" f "nominal" f)
> ;;   (r "source" -r "nominal" r)
> ;;   (dc "source" dc "nominal" dc)
> ;;   (pc "source" provide/contract-id-pc.9 "nominal" pc)
> ;;   (pcr "source" provide/contract-id-pcr.13 "nominal" pcr))
>
> -=-=-=-=-=-=-=-
>
> p.s. This is re https://github.com/greghendershott/racket-mode/issues/39

Posted on the users mailing list.