[racket-dev] define-require-syntax issue

From: Jay McCarthy (jay.mccarthy at gmail.com)
Date: Wed Oct 22 07:58:05 EDT 2014

#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.liebgold at 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.liebgold at 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


Posted on the dev mailing list.