[racket] implementing "require-redefine"
Thanks Neil for the ideas! I didn't think of looking how 'all-from-out'
works so I will start from there!
2011/11/9 Neil Toronto <neil.toronto at gmail.com>
> On 11/09/2011 07:29 AM, Ismael Figueroa Palet wrote:
>
>> Hi all, please help me with the following:
>>
>> I need to require a module, ideally with the same syntax as require,
>> then access to all the imported symbols and re-export them with the same
>> name but with a new definition, that is a wrapper for the original one.
>>
>> I think this should be done with a macro, but I don't know how to access
>> the imported symbols acquired with require.
>>
>> any pointers to documentation or ideas on how to implement this?
>>
>
> You'll want to implement something similar to `all-from-out'. I don't know
> exactly how it works; specifically, how it gets a list of imported
> identifiers. It's a "provide transformer" - you can search for that term in
> the docs. Also, don't be afraid to look at the code for `all-from-out'.
> It's defined in "collects/racket/private/**reqprov.rkt".
>
> Random tips:
>
> You'll need to make a provide transformer (using
> `make-provide-transformer) or a provide "pre-transformer" (using
> `make-provide-pre-transformer'**). Pre-transformers are expanded first,
> and return new provide syntax. Transformers are then expanded, and they
> return "exports", which are structs that contain information about provided
> symbols. In either case, you can get away with just manipulating syntax.
>
> Unlike regular macros, provide macros don't automatically expand until
> they expand into a basic form. If, say, in a pre-provide macro, you return
> new provide syntax that's *not* a basic provide form, you'll need to use
> `pre-expand-export' to expand it. There's a corresponding `expand-export'
> for provide macros.
>
> To make a wrapper, use `syntax-local-lift-expression' to lift the syntax
> of the wrapper's definition to the module level. You can then export it by
> having a pre-provide macro return `(provide wrapper-id)'.
>
> In dealing with requires and provides, you'll need to deal with phases.
> The mysterious "modes" mentioned in the docs on require and provide
> transformers are relative phases. I've found the following function helpful
> in a few places:
>
> (define-for-syntax (phases->abs-phases phases)
> (map (λ (phase) (and phase (+ phase (syntax-local-phase-level))))
> (if (null? phases) '(0) phases)))
>
> It turns relative phases into absolute phases, and ensures that there's
> always at least one. You'll want this if you want to look up identifiers to
> ensure they're defined, or lift a provide (so you can wrap it properly in a
> `for-meta'). If you can stick to just syntax transformations in your
> provide macros, you won't need it at all - just pass the relative phases
> through to `expand-export' and `pre-expand-export'.
>
> In existing provide macros like `all-from-out', you'll see "(apply append
> (map (lambda ...) ...))" in a few places. These map over identifiers and
> phases, and collect all the results. I've found "(append* (for/list ...))"
> and "(append* (for*/list ...))" are cleaner. (Of course, in "reqprov.rkt",
> the `for' macros haven't been defined yet.)
>
> I think this should be enough to get started on.
>
> Neil T
> ______________________________**___________________
> For list-related administrative tasks:
> http://lists.racket-lang.org/**listinfo/users<http://lists.racket-lang.org/listinfo/users>
--
Ismael
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20111109/f5afb625/attachment.html>