# Writing a macro that behaves differently depending on context

**URL:** <https://racket.discourse.group/t/writing-a-macro-that-behaves-differently-depending-on-context/536>\
**Category:** Questions & Answers\
**Tags:** macro, syntax, context\
**Created:** [January 7, 2022, 11:43pm UTC](https://racket.discourse.group/t/writing-a-macro-that-behaves-differently-depending-on-context/536 "2022-01-07T23:43:23Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![dimaugh](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/dimaugh/32/299_2.png) [@dimaugh](https://racket.discourse.group/u/dimaugh)\
**Post date:** [January 7, 2022, 11:43pm UTC](https://racket.discourse.group/t/writing-a-macro-that-behaves-differently-depending-on-context/536/1 "2022-01-07T23:43:23Z")

</div>

I'm trying to define a macro 'def' which behaves differently depending on where it appears. If it appears in the top-level, it expands to a normal 'define' and adds the definition to a hash. If it appears in a local context, it works more as a 'let' and nothing is added to the hash.  
So, how can a macro be aware of where it appears?

---

<div class="post-metadata">

**Author:** ![sorawee](https://avatars.discourse-cdn.com/v4/letter/s/ea5d25/32.png) [@sorawee](https://racket.discourse.group/u/sorawee)\
**Post date:** [January 8, 2022, 10:03am UTC](https://racket.discourse.group/t/writing-a-macro-that-behaves-differently-depending-on-context/536/2 "2022-01-08T10:03:47Z")

</div>

I’m a bit confused about the requirements. What do you mean by “expands to a normal” and “adds the definition to a hash”? In particular, is this a hash at run-time or compile-time? I also don’t understand what you mean by “it works more as a and nothing is added to the hash”. It looks like the sentence is incomplete.

In any case, yes, during macro expansion, you can use [`syntax-local-context`](https://docs.racket-lang.org/reference/stxtrans.html#%28def._%28%28quote._~23~25kernel%29._syntax-local-context%29%29) to see which context you are in. Here’s an example that illustrates how to use it:

```scheme
#lang racket

(define-syntax (test stx)
  (case (syntax-local-context)
    [(expression) #'"expression context"]
    [(top-level) #'"REPL context"]
    [(module module-begin) #'"module context"]
    [else #'"internal definition context"]))

test 
;=expand=> "module context"
;=eval=> "module context"

(values test)
;=expand=> (values "expression context") 
;=eval=> "expression context"

(let ()
  test) 
;=expand=> (let-values () "internal definition context") 
;=eval=> "internal definition context"

```

Furthermore, if you evaluate "test" at the REPL, you will get "REPL context" back.

---

<div class="post-metadata">

**Author:** ![dimaugh](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/dimaugh/32/299_2.png) [@dimaugh](https://racket.discourse.group/u/dimaugh)\
**Post date:** [January 8, 2022, 10:51am UTC](https://racket.discourse.group/t/writing-a-macro-that-behaves-differently-depending-on-context/536/3 "2022-01-08T10:51:57Z")

</div>

whoops, I put some Racket words between angle brackets so they were interpreted as HTML and didn't show in my final post. Edited using ' ' instead for clarity.  
Anyway, you pointed me in the direction I needed, thanks!
