That makes sense. It turns out I need replace-context *and* quasisyntax/loc (and back to absolute paths):
(define-require-syntax (gamelib stx) (syntax-case stx () ((_ name) (replace-context stx (quasisyntax/loc stx (file #,(format "~a/some/path/~a.dc" (current-directory) (syntax->datum #'name)))))) )) Without the ..syntax/loc form if I name the wrong file at my usage point the error location is the define-require-syntax declaration. Adding the /loc gets the correct usage location. Hrm. Hygiene is deep magic. Thanks, Dan On Wed, Oct 22, 2014 at 11:09 AM, Jay McCarthy <jay.mccar...@gmail.com> wrote: > If you have (require X) then the identifiers imported from X get the > lexical context of X. (Slight note: In something like (rename-in X [A > B]) then they get the context of A.) > > If a macro made X, then the lexical context is equivalent to #f, > because every macro application gets a fresh lexical context. (This > part of how "hygiene" is implemented.) > > So, since you macro produced an argument to require, the imports got > this empty lexical context. > > If you had produced a single identifier, then you could've produced it > with (datum->syntax stx 'symbol) and that would make it so the symbol > would have stx's context, rather than the default which is basically > #f. > > In the case of a file or submodule etc, when we construct a syntax > object with "syntax" (or quasisyntax or syntax/loc etc) there's no way > to specify what lexical context we want. (The "/loc" variants just > copy the source location, not the context.) Instead, we have to > construct the object and then go back and change the lexical context > using something like replace-context. > > Thus, the (file abc) that you produce now has the right stuff. It is > possible that you could've just replace the context of "file" or of > "abc" and got the same effect, but I'm not sure (it depends on how > "file" is implemented.) > > Jay > > > > > On Wed, Oct 22, 2014 at 2:03 PM, Dan Liebgold <dan.liebg...@gmail.com> > wrote: > > So, yeah... that appears to work! > > > > I use replace-context to give the resulting require syntax output the > > context of the original argument. Here's what the change looks like, > with my > > old way commented (unrelated note: path is actually relative): > > > > (define-require-syntax (gamelib stx) > > (syntax-case stx () > > ((_ name) > > ;;(quasisyntax/loc stx (file #,(format "../some/path/~a.dc" > (syntax->datum > > #'name))))) > > (replace-context stx #`(file #,(format "../some/path/~a.dc" > (syntax->datum > > #'name))))) > > )) > > > > I thought the quasisyntax/loc would be enough, but I guess > replace-context's > > increased thoroughness is necessary. > > > > So, is the problem that the identifiers imported by the require usage get > > the lexical context of the 'define-require-syntax' declaration (where I > use > > #' maybe)? I'm don't follow what exactly goes wrong with the imported > > identifiers. > > > > Thanks, > > Dan > > > > > > On Wed, Oct 22, 2014 at 4:58 AM, Jay McCarthy <jay.mccar...@gmail.com> > > wrote: > >> > >> #lang racket/base > >> > >> ;; This module has a binding and an effect, so we can see that it was > >> ;; required even when we can't get to it. > >> (module example racket/base > >> (define x 1) > >> (printf "I'm running here\n") > >> (provide x)) > >> > >> ;; If you comment this in, you'll see the "normal" way to require it. > >> > >> #; > >> (let () > >> (local-require (prefix-in no-macro: (submod "." example))) > >> (printf "NM x is ~a\n" no-macro:x) > >> (void)) > >> > >> ;; Here is the "obvious" macro of tihs form > >> (require racket/require-syntax) > >> (define-require-syntax macro1 > >> (syntax-rules () > >> [(_) (submod "." example)])) > >> > >> ;; If you comment this in, you'll see that the effect is run, meaning > >> ;; that it really does require the right thing. Also notice that since > >> ;; I'm using submodules, the problem ISN'T that `example1` is some how > >> ;; no the right binding for the module. In your example of an absolute > >> ;; path, it's even more clear that the path isn't wrong. > >> > >> #; > >> (let () > >> (local-require (prefix-in macro1: (macro1))) > >> ;; If you comment this in, you'll see that it is unbound. > >> #; > >> (printf "M1 x is ~a\n" macro1:x) > >> (void)) > >> > >> ;; Here is a more complicated version of the above macro. There's > >> ;; really only one meaningful difference and that's that we explicitly > >> ;; give the require syntax output the context of the CALL to > >> ;; macro2. If macro2 had an argument, it may make more sense to use > >> ;; that lexical context, because that argument probably came from the > >> ;; ultimate user of this require syntax (in case macro2 is used by > >> ;; another macro2) > >> (require (for-syntax racket/base > >> syntax/strip-context)) > >> (define-require-syntax macro2 > >> (λ (stx) > >> (syntax-case stx () > >> [(_) > >> (replace-context stx (syntax (submod "." example)))]))) > >> > >> ;; You may want to comment this out while looking at the other ones so > >> ;; you can be sure that this isn't the reason something is working. > >> > >> (let () > >> (local-require (prefix-in macro2: (macro2))) > >> (printf "M2 x is ~a\n" macro2:x) > >> (void)) > >> > >> On Tue, Oct 21, 2014 at 9:26 PM, Dan Liebgold <dan.liebg...@gmail.com> > >> wrote: > >> > If I do a (require (file <some absolute path>)) in a module, the > >> > provided > >> > stuff gets imported properly. > >> > > >> > If I do a special require form that uses define-require-syntax to > >> > generate > >> > an identical (file <...>) the specified module gets evaluated -- but > >> > (seemingly) nothing gets imported. > >> > > >> > Is there something special the define-require-syntax transformer needs > >> > to do > >> > besides generate a syntax object? > >> > > >> > samth mentioned on irc that it is probably a hygiene issue... > something > >> > about generating the right marks on the (file ...) form. > >> > > >> > -- > >> > Dan Liebgold [dan.liebg...@gmail.com] > >> > > >> > _________________________ > >> > Racket Developers list: > >> > http://lists.racket-lang.org/dev > >> > > >> > >> > >> > >> -- > >> Jay McCarthy > >> http://jeapostrophe.github.io > >> > >> "Wherefore, be not weary in well-doing, > >> for ye are laying the foundation of a great work. > >> And out of small things proceedeth that which is great." > >> - D&C 64:33 > > > > > > > > > > -- > > Dan Liebgold [dan.liebg...@gmail.com] > > > > -- > Jay McCarthy > http://jeapostrophe.github.io > > "Wherefore, be not weary in well-doing, > for ye are laying the foundation of a great work. > And out of small things proceedeth that which is great." > - D&C 64:33 > -- Dan Liebgold [dan.liebg...@gmail.com]
_________________________ Racket Developers list: http://lists.racket-lang.org/dev