# Syntax-local-introduce and module boundaries

**URL:** https://racket.discourse.group/t/syntax-local-introduce-and-module-boundaries/1157
**Category:** Questions & Answers
**Tags:** macro
**Created:** [July 18, 2022, 7:40am UTC](https://racket.discourse.group/t/syntax-local-introduce-and-module-boundaries/1157 "2022-07-18T07:40:26Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![Kalimehtar](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/kalimehtar/32/394_2.png) [@Kalimehtar](https://racket.discourse.group/u/Kalimehtar)
#### Post date: [July 18, 2022, 7:40am UTC](https://racket.discourse.group/t/syntax-local-introduce-and-module-boundaries/1157/1 "2022-07-18T07:40:26Z")

</div>

If I use syntax-local-introduce inside one module, then it works:

```scheme
(define-syntax (require-macro stx)
  (syntax-local-introduce #'(require racket/math)))

(define-syntax (define-macro stx)
  (syntax-local-introduce #'(define x 10)))

(require-macro)
pi
(define-macro)
x

```

But if I try to use it in another module, it fails:

```scheme
lib.rkt:
#lang racket/base
(require (for-syntax racket/base))
(provide require-macro define-macro)

(define-syntax (require-macro stx)
  (syntax-local-introduce #'(require racket/math)))

(define-syntax (define-macro stx)
  (syntax-local-introduce #'(define x 10)))

test.rkt:
#lang racket/base

(require "lib.rkt")

(require-macro)
pi ; this returns unbound identifier
(define-macro)
x ; this too

```

How to make macro introducing definition be usable through require?

---

<div class="post-metadata">

### Author: ![mflatt](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/mflatt/32/6_2.png) [@mflatt](https://racket.discourse.group/u/mflatt)
#### Post date: [July 20, 2022, 1:17pm UTC](https://racket.discourse.group/t/syntax-local-introduce-and-module-boundaries/1157/2 "2022-07-20T13:17:13Z")

</div>

The problem where is that `#'(require racket/math)` preserves the lexical context of the place where it occurs, which is not in the module where you wanted the bindings to be visible. The `syntax-local-introduce` call makes the syntax returned by the macro expansion look like it's not from a macro expansion, but that syntax is still from a different module.

You might want

```scheme
(define-syntax (require-macro stx)
  (datum->syntax stx '(require racket/math)))

```

Using `datum->syntax` with `stx` makes the result syntax look like it came from the same place as `stx`, which is the use of the `require-macro` form.

---

<div class="post-metadata">

### Author: ![ryanc](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/ryanc/32/71_2.png) [@ryanc](https://racket.discourse.group/u/ryanc)
#### Post date: [July 20, 2022, 1:26pm UTC](https://racket.discourse.group/t/syntax-local-introduce-and-module-boundaries/1157/3 "2022-07-20T13:26:19Z")

</div>

To nitpick: it should be something like

```scheme
(define-syntax (require-macro stx)
  (datum->syntax stx (list #'require 'racket/match)))

```

instead, because you want the local meaning of `require` (that is, Racket's `require` form), not whatever `require` might happen to mean at the macro use site.

---

<div class="post-metadata">

### Author: ![Kalimehtar](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/kalimehtar/32/394_2.png) [@Kalimehtar](https://racket.discourse.group/u/Kalimehtar)
#### Post date: [July 20, 2022, 2:00pm UTC](https://racket.discourse.group/t/syntax-local-introduce-and-module-boundaries/1157/4 "2022-07-20T14:00:38Z")

</div>

This way it works, but breaks DrRacket: I see no arrow to `pi` and no "imported from" popup.

`syntax-local-introduce` variant shows "imported from racket/math".

---

<div class="post-metadata">

### Author: ![EmEf](https://avatars.discourse-cdn.com/v4/letter/e/53a042/32.png) [@EmEf](https://racket.discourse.group/u/EmEf)
#### Post date: [July 20, 2022, 2:24pm UTC](https://racket.discourse.group/t/syntax-local-introduce-and-module-boundaries/1157/5 "2022-07-20T14:24:14Z")

</div>

```scheme
(datum->syntax stx … #’require … stx tsx)

```

---

<div class="post-metadata">

### Author: ![Kalimehtar](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/kalimehtar/32/394_2.png) [@Kalimehtar](https://racket.discourse.group/u/Kalimehtar)
#### Post date: [July 20, 2022, 7:41pm UTC](https://racket.discourse.group/t/syntax-local-introduce-and-module-boundaries/1157/6 "2022-07-20T19:41:41Z")

</div>

```scheme
(define-syntax (require-macro stx)
  (datum->syntax stx '(require racket/math) stx stx stx))

```

and

```scheme
(define-syntax (require-macro stx)
  (datum->syntax stx (list #'require 'racket/math) stx stx stx))

```

also don't work with DrRacket.

---

<div class="post-metadata">

### Author: ![Kalimehtar](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/kalimehtar/32/394_2.png) [@Kalimehtar](https://racket.discourse.group/u/Kalimehtar)
#### Post date: [July 23, 2022, 10:17am UTC](https://racket.discourse.group/t/syntax-local-introduce-and-module-boundaries/1157/7 "2022-07-23T10:17:23Z")

</div>

I've found the correct answer. It is:

```scheme
(define-syntax (require-macro stx)
  (datum->syntax stx (list #'require (datum->syntax stx 'racket/math stx stx))))

```

Thank you all for help.

---

<div class="post-metadata">

### Author: ![yanyingwang](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/yanyingwang/32/470_2.png) [@yanyingwang](https://racket.discourse.group/u/yanyingwang)
#### Post date: [July 28, 2022, 5:47pm UTC](https://racket.discourse.group/t/syntax-local-introduce-and-module-boundaries/1157/8 "2022-07-28T17:47:38Z")

</div>

I ran into the same question of 'require' recently. And I searched for it and it brought me here. So it seems to me the `(datum->syntax stx ...)` is a better choice for this similar cases. Then it came to me, why do we need the `syntax-local-introduce`? What is the proper usage of it?
