# Difference between Racket and Typed Racket with macro literals

**URL:** <https://racket.discourse.group/t/difference-between-racket-and-typed-racket-with-macro-literals/2946>\
**Category:** Questions & Answers\
**Created:** [June 2, 2024, 7:05pm UTC](https://racket.discourse.group/t/difference-between-racket-and-typed-racket-with-macro-literals/2946 "2024-06-02T19:05:53Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![shawnw](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/shawnw/32/1031_2.png) [@shawnw](https://racket.discourse.group/u/shawnw)\
**Post date:** [June 2, 2024, 7:05pm UTC](https://racket.discourse.group/t/difference-between-racket-and-typed-racket-with-macro-literals/2946/1 "2024-06-02T19:05:53Z")

</div>

With this untyped module:

```scheme
#lang racket/base

(require (for-syntax racket/base syntax/parse))
(provide choose one two)

(define-syntax (one stx)
  (raise-syntax-error stx "use of one outside of choose"))

(define-syntax (two stx)
  (raise-syntax-error stx "use of two outside of choose"))

(define-syntax (choose stx)
  (syntax-parse stx
    #:literals (one two)
    [(_ one) #'"You chose one"]
    [(_ two) #'"You chose two"]))

```

everything works as expected:

```scheme
$ racket
Welcome to Racket v8.13 [cs].
> (require "demo-untyped.rkt")
> (choose one)
"You chose one"
>

```

but with this Typed Racket version:

```scheme
#lang typed/racket/base

(require (for-syntax typed/racket/base syntax/parse))
(provide choose one two)

(define-syntax (one stx)
  (raise-syntax-error stx "use of one outside of choose"))

(define-syntax (two stx)
  (raise-syntax-error stx "use of two outside of choose"))

(define-syntax (choose stx)
  (syntax-parse stx
    #:literals (one two)
    [(_ one) #'"You chose one"]
    [(_ two) #'"You chose two"]))

```

trying to use it gives an error:

```scheme
$ racket -I typed/racket
Welcome to Racket v8.13 [cs].
> (require "demo-typed.rkt")
> (choose one)
string:1:0: choose: expected one of these identifiers: `one' or `two'
  at: one
  in: (choose one)
 [,bt for context]

```

I can't figure out why the exported literal identifiers aren't being used in the TR version but are in the untyped version. Any ideas? Or is this a bug?

---

<div class="post-metadata">

**Author:** ![shawnw](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/shawnw/32/1031_2.png) [@shawnw](https://racket.discourse.group/u/shawnw)\
**Post date:** [June 3, 2024, 4:14pm UTC](https://racket.discourse.group/t/difference-between-racket-and-typed-racket-with-macro-literals/2946/2 "2024-06-03T16:14:56Z")

</div>

Using `#:datum-literals` instead of `#:literals` makes it work, but I'm still wondering why the first way isn't working. Does Typed Racket wrap exported syntax in something that makes them not `free-identifier=?` to ones in the module they're defined in?

---

<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:** [June 3, 2024, 11:21pm UTC](https://racket.discourse.group/t/difference-between-racket-and-typed-racket-with-macro-literals/2946/3 "2024-06-03T23:21:10Z")

</div>

What if you `require` the `typed/racket/base` module, not in a REPL presumably using `racket/base`, but in a module explicitly also using `typed/racket/base`? (Therefore no typed =\> non-typed boundary involved?)

I ask because I wonder if this is related to Typed Racket exporting things wrapped in contracts for non-Typed Racket modules (in which case they are not the original things, but rather chaperones for the things).

---

<div class="post-metadata">

**Author:** ![shawnw](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/shawnw/32/1031_2.png) [@shawnw](https://racket.discourse.group/u/shawnw)\
**Post date:** [June 3, 2024, 11:37pm UTC](https://racket.discourse.group/t/difference-between-racket-and-typed-racket-with-macro-literals/2946/4 "2024-06-03T23:37:22Z")

</div>

I'm using a typed racket repl, but it doesn't make a difference if it's another typed module requiring it instead (That's how I originally discovered it).

---

<div class="post-metadata">

**Author:** ![usao](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/usao/32/1375_2.png) [@usao](https://racket.discourse.group/u/usao)\
**Post date:** [June 4, 2024, 5:54am UTC](https://racket.discourse.group/t/difference-between-racket-and-typed-racket-with-macro-literals/2946/5 "2024-06-04T05:54:25Z")

</div>

Typed Racket does something funky to bindings to make them work in different contexts (deep, shallow, optional, untyped), so `free-identifier=?` is confused. A way to work around this is to define the keywords in a separate module, then import the keywords in both the macro module and client modules (or re-export the keywords from the macro module, for that matter).

```scheme
#lang typed/racket/base
(module keyword typed/racket/base
  (require (for-syntax typed/racket/base))

  (provide one
           two)

  (define-syntax (one stx)
    (raise-syntax-error #f "use of one outside of choose"))

  (define-syntax (two stx)
    (raise-syntax-error #f "use of two outside of choose")))

(module macro typed/racket/base
  (require (submod ".." keyword)
           (for-syntax typed/racket/base
                       syntax/parse))

  (provide one ; re-export
           two ; re-export
           choose)

  (define-syntax (choose stx)
    (syntax-parse stx
      #:literals (one two)
      [(_ one) #'"You chose one"]
      [(_ two) #'"You chose two"])))

(require (submod "." macro))

(choose one)

(choose two)

```

---

<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:** [June 4, 2024, 2:35pm UTC](https://racket.discourse.group/t/difference-between-racket-and-typed-racket-with-macro-literals/2946/6 "2024-06-04T14:35:33Z")

</div>

Typed Racket wraps provided macros to protect them, just like it wraps provided values. Unfortunately, that means they don't compare equal to the ones inside the module, breaking this program.
