# Why isn't my macro hygienic?

**URL:** <https://racket.discourse.group/t/why-isnt-my-macro-hygienic/2881>\
**Category:** Questions & Answers\
**Tags:** question, macro\
**Created:** [April 24, 2024, 3:28am UTC](https://racket.discourse.group/t/why-isnt-my-macro-hygienic/2881 "2024-04-24T03:28:07Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![xiaoyu2006](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/xiaoyu2006/32/1682_2.png) [@xiaoyu2006](https://racket.discourse.group/u/xiaoyu2006)\
**Post date:** [April 24, 2024, 3:28am UTC](https://racket.discourse.group/t/why-isnt-my-macro-hygienic/2881/1 "2024-04-24T03:28:08Z")

</div>

Sorry for my newbie metaprogramming question. Say I have this macro:

```racket
#lang racket/base

(require (for-syntax racket/base))

;; Depends on map, eval, quote
(define-syntax (eval-emit stx)
  (syntax-case stx ()
    [(_ expr ...)
     (with-syntax
         ([exprs
           (cons 'quote (list (syntax->list #'(expr ...))))])
       #'(map eval exprs))]))

```

Which is trying to evaluate like a baby REPL. And I can:

```racket
> (eval-emit
      (define x 2)
      (define y 3)
      (+ x y)
      (* x y)
      (eval-emit
       (define z 5)
       (+ x y z)))
;; => '(void void 5 6 (void 10)) 

```

in the REPL (ignore the namespace issue). But if I try to do something nasty:

```racket
> (define map 1)
> (eval-emit 1 2)
;; => application: not a procedure;

```

The macro is not hygienic anymore. On the other hand:

```racket
> (define if 1)
> (and 1 2 3)
;; => 3

```

The built-in macro works fine. How do I achieve the same thing? Or is `eval-emit` designed wrongly from the very start and there exist better ways to do it?

---

<div class="post-metadata">

**Author:** ![jbclements](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/jbclements/32/11_2.png) [@jbclements](https://racket.discourse.group/u/jbclements)\
**Post date:** [April 24, 2024, 4:16am UTC](https://racket.discourse.group/t/why-isnt-my-macro-hygienic/2881/2 "2024-04-24T04:16:28Z")

</div>

Correct me if I'm wrong. I think what you're saying is that you want the `map` that's inserted by your macro to refer to the value for map that was in existence when the macro was defined. I claim that this is not a hygiene problem; the `map` inserted by your macro has the same binding as the one whose value you are changing later.

I also think that the problem you're seeing will disappear when you move to more substantial examples, where for instance the macro definition appears in a different module than the macro use.

... Instead, you'll have a whole bunch of _different_ problems :).

I think this is where I point you to Matthew Flatt's blog post about eval, and how actually you really didn't want to use eval at all.

Or maybe you should read the one about the top level being hopeless?

More generally, if you want to use `eval` in a way that doesn't wind up biting you in a nasty way later, you probably want to construct a complete module, and then use eval on that.

Let me return to the TL/DR: why is it that you want to use eval?

---

<div class="post-metadata">

**Author:** ![xiaoyu2006](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/xiaoyu2006/32/1682_2.png) [@xiaoyu2006](https://racket.discourse.group/u/xiaoyu2006)\
**Post date:** [April 24, 2024, 4:39am UTC](https://racket.discourse.group/t/why-isnt-my-macro-hygienic/2881/3 "2024-04-24T04:39:38Z")

</div>

The final product I am working on should be something like this:

```rkt
;; Say we have (define/expr name expr) that goes to
;; (begin
;; (define name expr)
;; name)

(foo
  (define/expr a (bar 'stub 'stub))
  (baz a 'stub))

```

Where `foo` act like a function call with arbritay length arguments but inside it new names can be bind to and referenced to.

Also I'm happy to read about Flatt's blog. Where can I find them?

---

<div class="post-metadata">

**Author:** ![jbclements](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/jbclements/32/11_2.png) [@jbclements](https://racket.discourse.group/u/jbclements)\
**Post date:** [April 24, 2024, 5:17am UTC](https://racket.discourse.group/t/why-isnt-my-macro-hygienic/2881/4 "2024-04-24T05:17:02Z")

</div>

Does this do what you want?

```scheme
#lang racket

(define-syntax (define/expr stx)
  (syntax-case stx ()
    [(_ name expr)
     #'(begin (define name expr) name)]))

(define/expr a 14)
a

```

?

---

<div class="post-metadata">

**Author:** ![jbclements](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/jbclements/32/11_2.png) [@jbclements](https://racket.discourse.group/u/jbclements)\
**Post date:** [April 24, 2024, 5:21am UTC](https://racket.discourse.group/t/why-isnt-my-macro-hygienic/2881/5 "2024-04-24T05:21:24Z")

</div>

Hmm... or, based on your use case, it sounds like perhaps you want the name to be bound at the top level, as well? In that case, I think I personally would look into a whole-module transformation that inserts stub definitions at the top level, and then replaces uses of define/expr with uses of `set!`. This could potentially be some kind of tricky re-binding-app-and-every-other-form to transitively hoist the definition out, but I'd be inclined to just do it as a whole-module transformation.  
'  
There may _very well_ be a much more elegant way to do it than the just-traverse-the-module approach that I'm describing.

---

<div class="post-metadata">

**Author:** ![xiaoyu2006](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/xiaoyu2006/32/1682_2.png) [@xiaoyu2006](https://racket.discourse.group/u/xiaoyu2006)\
**Post date:** [April 24, 2024, 5:30am UTC](https://racket.discourse.group/t/why-isnt-my-macro-hygienic/2881/6 "2024-04-24T05:30:04Z")

</div>

Indeed your `define/expr` works but (to further clarify) I'm having trouble with `foo` which will utilize `eval-emit` to accomplish its functionality. i.e. Having a baby REPL inside it to keep track of side-effects (bindings) and get what expressions eval into.

And also thanks for your support \<3

---

<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:** [April 24, 2024, 9:38am UTC](https://racket.discourse.group/t/why-isnt-my-macro-hygienic/2881/7 "2024-04-24T09:38:03Z")

</div>

> [@xiaoyu2006](#):
>
> But if I try to do something nasty

Are you intended to define both the macro and the new `map` variable in the repl? I can't reproduce this error by defining the macro in a module and importing it into the repl.

If you mean to do so, then the question might be how an identifier refers to a particular binding.

According to [the racket reference](https://docs.racket-lang.org/reference/syntax-model.html#(part._id-model)),

> An identifier refers to a particular binding when the reference’s symbol and the identifier’s symbol are the same, and when the reference’s [scope set](https://docs.racket-lang.org/reference/syntax-model.html#%28tech._scope._set%29) is a superset of the binding’s [scope set](https://docs.racket-lang.org/reference/syntax-model.html#%28tech._scope._set%29). For a given identifier, multiple bindings may have [scope sets](https://docs.racket-lang.org/reference/syntax-model.html#%28tech._scope._set%29) that are subsets of the identifier’s; in that case, the identifier refers to the binding whose set is a superset of all others; if no such binding exists, the reference is ambiguous (and triggers a syntax error if it is parsed as an expression). A binding shadows any [binding](https://docs.racket-lang.org/reference/syntax-model.html#%28tech._binding%29) (i.e., it is shadowing any [binding](https://docs.racket-lang.org/reference/syntax-model.html#%28tech._binding%29)) with the same symbol but a subset of scopes.

That is to say, the original `map` binding is shallowed.

---

<div class="post-metadata">

**Author:** ![xiaoyu2006](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/xiaoyu2006/32/1682_2.png) [@xiaoyu2006](https://racket.discourse.group/u/xiaoyu2006)\
**Post date:** [April 24, 2024, 9:58am UTC](https://racket.discourse.group/t/why-isnt-my-macro-hygienic/2881/8 "2024-04-24T09:58:40Z")

</div>

I clicked the `Run` button in DrRacket and used the REPL there.

It turns out that DrRacket `Run` is not equivalent to `require` a file. Ouch. Problem solved.

But on a side note is my approach "idomatic"? I don't feel good using `eval`.

---

<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:** [April 24, 2024, 2:15pm UTC](https://racket.discourse.group/t/why-isnt-my-macro-hygienic/2881/9 "2024-04-24T14:15:43Z")

</div>

As I understand it, `eval` is typically used with namespaces. If you don't use customized namespaces, you can write a small DSL that recognizes and handles statements, expressions, etc.
