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

From: Sam Tobin-Hochstadt (samth at cs.indiana.edu)
Date: Tue Jul 22 16:50:13 EDT 2014

On Tue, Jul 22, 2014 at 4:42 PM, Greg Hendershott
<greghendershott at gmail.com> wrote:
> 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?

`identifier-binding` is the right tool for following renamings, as I
think your first email describes.

`contract-out` is really something different -- you aren't actually
trying to go to the definition of the thing referenced in this case.
`contract-out` creates a new definition with the contract on it, and
then provides that under the original name.

I think the contract library could provide a syntax-property on the
identifiers it expands into to point to the original identifier, but
it doesn't do this currently.

Sam

> 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
> ____________________
>   Racket Users list:
>   http://lists.racket-lang.org/users

Posted on the users mailing list.