[racket-dev] Preserving source location in macro-generating macros, in collects

From: Neil Toronto (neil.toronto at gmail.com)
Date: Fri Oct 7 12:15:19 EDT 2011

On 10/07/2011 09:56 AM, Robby Findler wrote:
> On Fri, Oct 7, 2011 at 10:35 AM, Neil Toronto<neil.toronto at gmail.com>  wrote:
>> Why I care: I wrote a macro that both defines a contracted function and
>> defines a macro that expands to a Scribble 'defproc' with the same contract.
>> With the source locations gone (recursively), Scribble can't format the
>> contracts, and I end up with things like (real-in01) instead of (real-in 0
>> 1).
>>
>> (I know about scribble/srcdoc, but dependencies keep me from using it.)
>
> Can you say more about the dependencies issue?

Sure! I have a module "parameters.rkt" that everything in the collection 
depends on. It has its own page in the docs as well. The best way to 
explain some of them - like plot-x-transform, which you can use to do 
log-scale axes - is to use an example. But I can't refer to 'plot' 
inside "parameters.rkt".

I think.

Here's the thing. When I first looked into it, I wasn't making a 
collection; 'plot' was just a directory on my hard drive. I tried using 
'scribble/srcloc', and it kept not finding modules. So what I think is 
true about it are often assumptions and inferences.

For example, I think that it wouldn't give me the freedom to present the 
API in the order/grouping I want it in, for the cases where the best 
order/grouping in the docs is different from the best order/grouping in 
the code.

>> Suppose I have a "location reporter" macro, which is generated by a macro:
>>
>>
>> #lang racket
>>
>> (require (for-syntax syntax/srcloc))
>>
>> (provide location-reporter)
>>
>> (define-syntax (make-location-reporter stx)
>>   (syntax-case stx ()
>>     [(_ name)  #'(define-syntax (name inner-stx)
>>                    (syntax-case inner-stx ()
>>                      [(_)  #`#,(source-location->string #'name)]))]))
>>
>> (make-location-reporter location-reporter)
>>
>>
>> If I compile this in DrRacket, require it from another module, and do
>>
>>     (location-reporter)
>>
>> it expands to
>>
>>     "<collects>/plot/location-reporter.rkt:13.24"
>>
>> as I expect. But if I compile it as part of "raco setup", it expands to
>>
>>     "<collects>/plot/location-reporter.rkt"
>>
>> I understand that stripping source locations is an optimization. But is
>> there a way to turn it off, or preserve them, recursively, another way?
>>
>> Also, exactly how is the location information disappearing? Does it happen
>> when 'name' above is double-syntax-quoted?
>
> When a syntax object is compiled and written to a .zo file, all that
> information is stripped. You have to write use another function at
> compile time that walks over the syntax objects and records the source
> locations and then saves them in some way that is not a syntax object
> literal. Then restore them.

I was afraid of that. Probably not too hard, but not a cakewalk, either.

Neil T


Posted on the dev mailing list.