# Macro in Racket language?

**URL:** <https://racket.discourse.group/t/macro-in-racket-language/1709>\
**Category:** Questions & Answers\
**Tags:** macro\
**Created:** [February 13, 2023, 12:51pm UTC](https://racket.discourse.group/t/macro-in-racket-language/1709 "2023-02-13T12:51:48Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Antigen-11](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/antigen-11/32/1813_2.png) [@Antigen-11](https://racket.discourse.group/u/Antigen-11)\
**Post date:** [February 13, 2023, 12:51pm UTC](https://racket.discourse.group/t/macro-in-racket-language/1709/1 "2023-02-13T12:51:49Z")

</div>

```scheme
> (version)
"8.8"
> (require (for-syntax racket/base))
> (define-syntax-rule (make-module n (l ...) i b)
    (module n racket/base
      (require l ...)
      (provide i)
      (define i b)))
> (make-module t () x 1)
string:1:20: ?: literal data is not allowed;
 no #%datum syntax transformer is bound
  at: 1
 [,bt for context]
> (make-module t (racket/base) x 1)

```

Anyway, the macro can be expanded successfully at last, but I don't want to import the library twice. What should I do? Or is this documented?

---

<div class="post-metadata">

**Author:** ![soegaard](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/soegaard/32/19_2.png) [@soegaard](https://racket.discourse.group/u/soegaard)\
**Post date:** [February 13, 2023, 2:08pm UTC](https://racket.discourse.group/t/macro-in-racket-language/1709/2 "2023-02-13T14:08:25Z")

</div>

I think the problem is how `#%datum` is introduced.

When `#%datum` is introduced it gets the lexical information from the  
syntax object (that needs to wrapped in `#%datum`).  
In the form `(make-module t () x 1)` the `1` will become `(#%datum . 1)`  
but the `#%datum` has lexical information from outside the `t` module.  
So you get the "no #%datum syntax transformer is bound" error.

How to solve the problem depends on where you want `b` to get its context.

One option:

```scheme
(define-syntax (make-module stx)
  (syntax-case stx ()
    [(_make-module n (l ...) i b)
     (with-syntax ([b (datum->syntax #'stx (syntax->datum #'b))])
       (syntax/loc stx
         (module n racket/base
           (require l ...)
           (provide i)
           (define i b))))]))

```

---

<div class="post-metadata">

**Author:** ![Antigen-11](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/antigen-11/32/1813_2.png) [@Antigen-11](https://racket.discourse.group/u/Antigen-11)\
**Post date:** [February 13, 2023, 2:16pm UTC](https://racket.discourse.group/t/macro-in-racket-language/1709/3 "2023-02-13T14:16:10Z")

</div>

Thanks for your kind explanation, sir!

But there still remains a question. Why does the error just disappear when we explicitly import the library in the `t` module?

---

<div class="post-metadata">

**Author:** ![soegaard](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/soegaard/32/19_2.png) [@soegaard](https://racket.discourse.group/u/soegaard)\
**Post date:** [February 13, 2023, 2:23pm UTC](https://racket.discourse.group/t/macro-in-racket-language/1709/4 "2023-02-13T14:23:34Z")

</div>

It boils down to how `(require module-path)` works.

> (require module-path)

> Imports all exported bindings from the named module,  
> using the export name for the local identifiers.  
> The lexical context of the module-path form determines the  
> context of the introduced identifiers, a ...

So in `(make-module t (racket/base) x 1)` the `racket/base` and `1`  
have the same lexical context. When inserted in `(require l ...)`  
the imported binding for `#%datum` will have the same context as `1`.  
And when the implicit `#%datum` is added, it will now be bound.

---

<div class="post-metadata">

**Author:** ![Antigen-11](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/antigen-11/32/1813_2.png) [@Antigen-11](https://racket.discourse.group/u/Antigen-11)\
**Post date:** [February 13, 2023, 2:27pm UTC](https://racket.discourse.group/t/macro-in-racket-language/1709/5 "2023-02-13T14:27:16Z")

</div>

Thank you very much, sir!

---

<div class="post-metadata">

**Author:** ![Antigen-11](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/antigen-11/32/1813_2.png) [@Antigen-11](https://racket.discourse.group/u/Antigen-11)\
**Post date:** [February 13, 2023, 2:41pm UTC](https://racket.discourse.group/t/macro-in-racket-language/1709/6 "2023-02-13T14:41:59Z")

</div>

But according to the [documentation](https://docs.racket-lang.org/reference/module.html#%28form._%28%28quote._~23~25kernel%29._module%29%29),

> The module-path form must be as for [require](https://docs.racket-lang.org/reference/require.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._require%29%29), and it supplies the initial bindings for the body forms. That is, it is treated like a ([require](https://docs.racket-lang.org/reference/require.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._require%29%29) module-path) prefix before the forms, except that the bindings introduced by module-path can be shadowed by definitions and [require](https://docs.racket-lang.org/reference/require.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._require%29%29)s in the module body forms.

Is this case an exception?

---

<div class="post-metadata">

**Author:** ![soegaard](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/soegaard/32/19_2.png) [@soegaard](https://racket.discourse.group/u/soegaard)\
**Post date:** [February 13, 2023, 3:07pm UTC](https://racket.discourse.group/t/macro-in-racket-language/1709/7 "2023-02-13T15:07:47Z")

</div>

In

```scheme
(module n racket/base ...)

```

the context of the racket/base is "inside the module n".

Likewise, in:

```scheme
(module n racket/base 
   (require racket/base)
    ...)

```

the context of `racket/base` is also inside module `n`, so this is fully redundant.

However, in your example `(make-module t (racket/base) x 1)` the context of  
`racket/base` is "from outside the module n", so the bindings of `(require racket/base)`  
will get that context.

---

<div class="post-metadata">

**Author:** ![Antigen-11](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/antigen-11/32/1813_2.png) [@Antigen-11](https://racket.discourse.group/u/Antigen-11)\
**Post date:** [February 13, 2023, 3:09pm UTC](https://racket.discourse.group/t/macro-in-racket-language/1709/8 "2023-02-13T15:09:37Z")

</div>

Oh, I see. Sorry for bothering you!
