# Failed to match syntax-case for some literal names if using read-syntax

**URL:** <https://racket.discourse.group/t/failed-to-match-syntax-case-for-some-literal-names-if-using-read-syntax/1583>\
**Category:** Questions & Answers\
**Tags:** macro, syntax\
**Created:** [December 28, 2022, 12:07am UTC](https://racket.discourse.group/t/failed-to-match-syntax-case-for-some-literal-names-if-using-read-syntax/1583 "2022-12-28T00:07:04Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![corpix](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/corpix/32/925_2.png) [@corpix](https://racket.discourse.group/u/corpix)\
**Post date:** [December 28, 2022, 12:07am UTC](https://racket.discourse.group/t/failed-to-match-syntax-case-for-some-literal-names-if-using-read-syntax/1583/1 "2022-12-28T00:07:04Z")

</div>

Hi. Can't understand why I can't match some `literal-id`'s with `syntax-case`.

Here is a successful match example:

```scheme
> (let ((stx #'(load 'hello)))
    (syntax-case stx (load)
      ((load expr) (syntax expr))))
#<syntax::73:19 'hello>

```

But if we use `read-syntax` then it fails for some unknown reason:

```scheme
> (let ((stx (read-syntax "repl" (open-input-string "(load 'hello)"))))
    (syntax-case stx (load)
      ((load expr) (syntax expr))))
; repl::1: load: bad syntax
; in: (load (quote hello))
; Source locations:
; repl:1:0

```

If we change `literal-id` to something which is not available in current namespace then it is working:

```scheme
> (let ((stx (read-syntax "repl" (open-input-string "(xxx 'hello)"))))
    (syntax-case stx (xxx)
      ((xxx expr) (syntax expr))))
#<syntax:repl::6 'hello>

```

Could somebody please explain why this is not working and how could I fix this?  
Thank you.

---

<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:** [December 28, 2022, 1:54am UTC](https://racket.discourse.group/t/failed-to-match-syntax-case-for-some-literal-names-if-using-read-syntax/1583/2 "2022-12-28T01:54:20Z")

</div>

According to the doc of `syntax-case`:

> An id that has the same binding as a literal-id matches a syntax object that is an identifier with the same binding in the sense of [free-identifier=?](https://docs.racket-lang.org/reference/stxcmp.html#%28def._%28%28quote._~23~25kernel%29._free-identifier~3d~3f%29%29). The match does not introduce any [pattern variables](https://docs.racket-lang.org/reference/stx-patterns.html#%28tech._pattern._variable%29).

When you use `read-syntax`, you get a syntax object with empty lexical context. However, `load` that you are trying to match against is `load` from `#lang racket`. Therefore, they don’t match according to free-identifier=?.

There are a couple of possibilities to make them match.

(1) Add the current lexical context to the syntax object. This can be done by using `replace-context`. E.g.

```scheme
#lang racket

(require syntax/strip-context)

(let [(stx (replace-context
            #'here
            (read-syntax
             "repl"
             (open-input-string "(load 'hello)"))))]
  (syntax-case stx (load)
    [(load expr) (syntax expr)]))

```

(2) Don’t use `literal-id` in `syntax-case`; instead use a side-condition that checks textual equivalence.

```scheme
#lang racket

(let [(stx (read-syntax
            "repl"
            (open-input-string "(load 'hello)")))]
  (syntax-case stx ()
    [(load expr)
     (and (identifier? #'load) (eq? 'load (syntax-e #'load)))
     (syntax expr)]))

```

(3) Use `syntax-parse`‘s `~datum`.

```scheme
#lang racket

(require syntax/parse)

(let [(stx (read-syntax
            "repl"
            (open-input-string "(load 'hello)")))]
  (syntax-parse stx
    [({~datum load} expr)
     (syntax expr)]))

```

Note that (2) and (3) are essentially equivalent (resulting `expr` has empty lexical context), but (1) is not (resulting `expr` has the same lexical context as `#'here`). Depending on what you want to do, one might be more appropriate than another.
