# Parsack: cannot reference an identifier before its definition

**URL:** <https://racket.discourse.group/t/parsack-cannot-reference-an-identifier-before-its-definition/2349>\
**Category:** Questions & Answers\
**Created:** [September 29, 2023, 11:21am UTC](https://racket.discourse.group/t/parsack-cannot-reference-an-identifier-before-its-definition/2349 "2023-09-29T11:21:56Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![indrjo](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/indrjo/32/1346_2.png) [@indrjo](https://racket.discourse.group/u/indrjo)\
**Post date:** [September 29, 2023, 11:21am UTC](https://racket.discourse.group/t/parsack-cannot-reference-an-identifier-before-its-definition/2349/1 "2023-09-29T11:21:56Z")

</div>

I wrote some code in Haskell that I'd like to translate in Racket. It's about Parsec and Parsack.

```scheme
#lang racket

(require parsack)

(define quote-marks "'\"`")

(define quoted-name
  (between (oneOf quote-marks)
           (oneOf quote-marks)
           (many1 (noneOf quote-marks))))

(define not-found
  (>>= quoted-name
       (λ (name)
         (>> (>> $spaces
                 (string "not found"))
             (return (list->string name))))))

(define not-founds
  (choice
   (list
    (>> $eof
        (return '()))
    (try (>>= not-found
              (λ (name)
                (>>= not-founds
                     (λ (others) (return (cons name others)))))))
    (>> $anyChar
        not-founds))))

```

The error is:

```scheme
not-founds: undefined;
 cannot reference an identifier before its definition

```

At first, I thought it was some typo within my code, but it isn't.

It seems that using `>>=` instead of `>>` makes the code work. I mean:

```scheme
#lang racket

(require parsack)

(define quote-marks "'\"`")

(define quoted-name
  (between (oneOf quote-marks)
           (oneOf quote-marks)
           (many1 (noneOf quote-marks))))

(define not-found
  (>>= quoted-name
       (λ (name)
         (>> (>> $spaces
                 (string "not found"))
             (return (list->string name))))))

(define not-founds
  (choice
   (list
    (>> $eof
        (return '()))
    (try (>>= not-found
              (λ (name)
                (>>= not-founds
                     (λ (others) (return (cons name others)))))))
    ;; !!! here !!!
    (>>= $anyChar
        (λ (_) not-founds)))))

```

What am I missing here?

---

<div class="post-metadata">

**Author:** ![soegaard](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/soegaard/32/19_2.png) [@soegaard](https://racket.discourse.group/u/soegaard)\
**Post date:** [September 29, 2023, 12:59pm UTC](https://racket.discourse.group/t/parsack-cannot-reference-an-identifier-before-its-definition/2349/2 "2023-09-29T12:59:41Z")

</div>

You'll get the same error from `(define a a)`.  
Note that `(define a (λ () a))` works.

The semantics of `(define id expr)` is more or less:

1. Bind `id` to "the undefined value".
2. Evaluate `expr` and get a value v.
3. Assign `v` to `id`.

If during the evaluation of `expr` there is a reference to an undefined variable,  
an error is thrown.

Try for example:

```scheme
(define b (begin (display 1) b))

```

The usual fix of `(define a a)` is to use a thunk on the right hand side:

```scheme
(define a (λ () a))

```

The lambda expression can be evaluated without evaluting any references to `a`,  
so the error is avoided. Now `a` is a function, so when you refer to `a` write `(a)`.

It's just one of the differences between a strict and lazy language that you get used to over time.

---

<div class="post-metadata">

**Author:** ![indrjo](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/indrjo/32/1346_2.png) [@indrjo](https://racket.discourse.group/u/indrjo)\
**Post date:** [October 10, 2023, 12:08pm UTC](https://racket.discourse.group/t/parsack-cannot-reference-an-identifier-before-its-definition/2349/3 "2023-10-10T12:08:36Z")

</div>

Thank you for your time. I have been reading stuff these days, and I have tried to define (in my module) `>>` _as a syntactic element_ (pardon my choice of words) rather than as a function.

```scheme
(define-syntax-rule (>> f1 f2)
  (>>= f1 (λ (_) f2)))

```

Is this a solution, if I want to stick to Haskell for this piece of code? It seems to work, but I don't want it to mess with the library.
