# Imported syntax class works different from syntax class copy-pasted into file

**URL:** <https://racket.discourse.group/t/imported-syntax-class-works-different-from-syntax-class-copy-pasted-into-file/3507>\
**Category:** Questions & Answers\
**Created:** [January 21, 2025, 7:35pm UTC](https://racket.discourse.group/t/imported-syntax-class-works-different-from-syntax-class-copy-pasted-into-file/3507 "2025-01-21T19:35:45Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![sora22](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/sora22/32/2622_2.png) [@sora22](https://racket.discourse.group/u/sora22)\
**Post date:** [January 21, 2025, 7:35pm UTC](https://racket.discourse.group/t/imported-syntax-class-works-different-from-syntax-class-copy-pasted-into-file/3507/1 "2025-01-21T19:35:45Z")

</div>

I'm currently trying to reuse some syntax classes that I've made, and want to match certain identifiers within them. These syntax classes produce an error if I attempt to import them rather than defining them directly within the macro I am writing. This is a small breaking example I could come up with:

This works fine

```scheme
#lang racket/base

(require (for-syntax racket/base
                     syntax/parse))

(define-syntax (test stx)
  (define-syntax-class test-class
    (pattern ((~literal list) (~var x) (~var y))))
  
  (syntax-parse stx
    [(_ (~var list-expr test-class)) #'(void)]))

(test (list '(a b c) 1))

```

This produces an error stating "expected the identifier `list' parsing context: while parsing test-class in: list":

```scheme
;; some-syntax-classes.rkt
#lang racket/base

(require syntax/parse)

(provide (all-defined-out))

(define-syntax-class test-class
  (pattern ((~literal list) (~var x) (~var y))))

```

```scheme
#lang racket/base

(require (for-syntax racket/base
                     syntax/parse
                     "some-syntax-classes.rkt"))

(define-syntax (test stx)
  (syntax-parse stx
    [(_ (~var list-expr test-class)) #'(void)]))

(test (list '(a b c) 1))

```

Any idea what I'm doing wrong?

---

<div class="post-metadata">

**Author:** ![greghendershott](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/greghendershott/32/98_2.png) [@greghendershott](https://racket.discourse.group/u/greghendershott)\
**Post date:** [January 21, 2025, 8:47pm UTC](https://racket.discourse.group/t/imported-syntax-class-works-different-from-syntax-class-copy-pasted-into-file/3507/2 "2025-01-21T20:47:48Z")

</div>

So `~literal` matches an _identifier_ -- including a phase as well as a symbol: It's "`list` _at some specific phase level_".

In your first example, where the syntax class is defined at phase 1 inside the `define-syntax`, the `list` identifier in `(~literal list)` is the one at phase 1.

But in your second example, where the syntax class is defined at phase 0, the `list` identifier in `(~literal list)` is the one at phase 0.

That doesn't match the `list` at phase 1 in the expansion of `test`. So the error.

* * *

One thing you could do, in your second example, is change `(~literal list)` to `(~literal list #:phase 1)`.

As in the following. [Note: Just for my own convenience, I changed your two-file example into one file -- with a submodule `m` playing the role of `some-syntax-classes.rkt`.]

```scheme
#lang racket/base

(module m racket/base ;~= some-syntax-classes.rkt
  (require syntax/parse)

  (provide (all-defined-out))

  (define-syntax-class test-class
    (pattern ((~literal list #:phase 1) (~var x) (~var y)))))

(require (for-syntax racket/base
                     syntax/parse
                     'm)) ;~= some-syntax-classes.rkt

(define-syntax (test stx)
  (syntax-parse stx
    [(_ (~var list-expr test-class)) #'(void)]))

(test (list '(a b c) 1))

```

---

<div class="post-metadata">

**Author:** ![sora22](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/sora22/32/2622_2.png) [@sora22](https://racket.discourse.group/u/sora22)\
**Post date:** [January 21, 2025, 9:10pm UTC](https://racket.discourse.group/t/imported-syntax-class-works-different-from-syntax-class-copy-pasted-into-file/3507/3 "2025-01-21T21:10:13Z")

</div>

That solved my problem! Didn't know I could specify a phase level for it, thank you so much for your help

---

<div class="post-metadata">

**Author:** ![greghendershott](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/greghendershott/32/98_2.png) [@greghendershott](https://racket.discourse.group/u/greghendershott)\
**Post date:** [January 21, 2025, 9:18pm UTC](https://racket.discourse.group/t/imported-syntax-class-works-different-from-syntax-class-copy-pasted-into-file/3507/4 "2025-01-21T21:18:43Z")

</div>

Keep in mind there are various ways to handle this. Some may be more "ergonomic" solutions, if you're writing a lot of this stuff.

For example you could:

1. Use `define-literal-set` to name a variety of symbols (`list`, `cons`, whatever, etc.).
2. Use the `#:literal-sets` option to use that whole set at a certain phase level.
3. Now in your patterns you can just write `list` (not even need `(~literal list)` anymore, much less `(~literal list #:phase 1)`).

---

<div class="post-metadata">

**Author:** ![benknoble](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/benknoble/32/16_2.png) [@benknoble](https://racket.discourse.group/u/benknoble)\
**Post date:** [January 21, 2025, 9:21pm UTC](https://racket.discourse.group/t/imported-syntax-class-works-different-from-syntax-class-copy-pasted-into-file/3507/5 "2025-01-21T21:21:37Z")

</div>

2 other options I can think of:

- use `~datum`. A bit discouraged, but useful when you only care about  
the textual content and don't want to allow it to be renamed (`cond`  
recognizes `else` by binding, which means it works through renames but  
is a bit confusing if `else` is lexically shadowed).
- create, provide, and consistently use your _own_ binding. If you  
don't need its value, it can be as simple as `(define my-marker #f)`,  
as long as you're consistent about the phasing use as Greg pointed  
out.
