# Wrap a macro injecting bindings in another macro

**URL:** https://racket.discourse.group/t/wrap-a-macro-injecting-bindings-in-another-macro/1406
**Category:** Questions & Answers
**Tags:** macro
**Created:** [October 19, 2022, 2:43pm UTC](https://racket.discourse.group/t/wrap-a-macro-injecting-bindings-in-another-macro/1406 "2022-10-19T14:43:46Z")
**Posts on this page:** 1
**Showing post:** 2

<div class="post-metadata">

### Author: ![samth](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/samth/32/3_2.png) [@samth](https://racket.discourse.group/u/samth)
#### Post date: [October 19, 2022, 4:22pm UTC](https://racket.discourse.group/t/wrap-a-macro-injecting-bindings-in-another-macro/1406/2 "2022-10-19T16:22:41Z")

</div>

This is a classic program in the uncomposability of unhygenic macros. (This is discussed some in the syntax-parameters paper.) Basically, the interface of `auto-hash-ref/:` has as part of its interface the syntax of the whole form, which is where you get the syntactic context for all the variable bindings you insert. Then your `lambda/:` macro creates that syntax in its body, so that the bindings of :a and :b have the syntactic contexts of the expansion of `lambda/:` instead of its input.

The best solution is to (a) make it clear in the description of `auto-hash-ref/:` where it takes syntactic context from (b) choose something other than the whole form (such as the name of the hash table) and (c) ensure that the syntactic context of that comes from the input (which it does for that choice in your `lambda/:` macro). Basically you would change `stx` to `#'id` in the first argument to `datum->syntax` [here](https://git.marvid.fr/scolobb/dds/src/branch/master/utils.rkt#L129).

Unfortunately, even if you follow those rules, you will often need to write unhygienic macros to abstract over `auto-hash-ref/:`. For example, if you want to write this macro:

```scheme
(define-syntax-rule (auto-lambda body) (lambda (i) (auto-hash-ref/: i body)))

```

there is no way to write it as a hygienic macro and have it do what you want. Instead, even with the change I suggest, you would write:

```scheme
(define-syntax (auto-lambda stx)
   (syntax-parse stx
     [(_ b:expr)
      #:with i (format-id #'b "i")
      (lambda (i) (auto-hash-ref/: i body))]))

```

---

_[View the full topic](https://racket.discourse.group/t/wrap-a-macro-injecting-bindings-in-another-macro/1406)._
