title: Scheme R5RS - Undefined identifier
body: <p>I'm trying to test some code from a textbook "Teaching Nondeterministic and Universal Automata using Scheme". It's Scheme, I've configured DrRacket as R5RS.</p>
  
  <p>I copied the define part of the code, but it's still complaining</p>
  
  <blockquote>
    <p>reference to undefined identifier: read-only-tape</p>
  </blockquote>
  
  <p>Here's the relevant code.</p>
  
  <pre><code>(define tape
    (lambda()
      (let((blank '$))
        (let ((left-part(list blank))
              (right-part(list blank)))
          (lambda message
            (case(car message)
              ((init!)
               (set! left-part(reverse(caadr message)))
               (set! right-part(cadadr message)))
              ((write!)
               (if(equal? right-part(list blank))
                  (set! right-part (cons(cadr message) right-part))
                  (set! right-part (cons(cadr message)(cdr right-part)))))
              ((left!)
               (set! right-part (cons (car left-part) right-part))
               (if(not(equal? left-part (list blank)))
                  (set! left-part(cdr left-part))))
              ((right!)
               (set! left-part (cons (car right-part) left-part))
               (if (not (equal? right-part (list blank)))
                   (set! right-part (cdr right-part))))
              ((show)
               (list (reverse left-part) right-part))
              ((read)
               (car right-part))
              (else (error 'rape "Message ~a cannot be evaluated" (car message)))))))))
  
  (define read-only-tape
    (lambda()
      (let ((tape-obj (tape)))
        (lambda message
          (case(car message)
            ((reconfig!)(tape-obj 'right))
            ((left! right! write!)
             (error 'message "~a is prohibited for read-only-tapes" (car message)))
            (else(apply tape-obj message)))))))
  </code></pre>
  
  <p>And it's using the read-only-tape here:</p>
  
  <pre><code>(define automaton
    (lambda(start)
          (eval
           '(letrec
             ((q0(lambda(tape)
                   (printf "~a~n~a~n" (contents tape) 'q0)
                   (case (at tape)
                     ((a)(reconfig! tape)(q2 tape))
                     ((b)(reconfig! tape)(q1 tape))
                     (else #f))))
              (q1(lambda(tape)
                   (printf "~a~n~a~n" (contents tape) 'q1)
                   (case (at tape)
                     ((a)(reconfig! tape)(q5 tape))
                     ((b)(reconfig! tape)(q5 tape))
                     (($) #t)
                     (else #f))))
              (q2(lambda(tape)
                   (printf "~a~n~a~n" (contents tape) 'q2)
                   (case (at tape)
                     ((a)(reconfig! tape)(q3 tape))
                     ((b)(reconfig! tape)(q6 tape))
                     (else #f))))
              (q3(lambda(tape)
                   (printf "~a~n~a~n" (contents tape) 'q3)
                   (case (at tape)
                     ((a)(reconfig! tape)(q3 tape))
                     ((b)(reconfig! tape)(q4 tape))
                     (else #f))))
              (q4(lambda(tape)
                   (printf "~a~n~a~n" (contents tape) 'q4)
                   (case (at tape)
                     ((a)(reconfig! tape)(q5 tape))
                     ((b)(reconfig! tape)(q5 tape))
                     (($) #t)
                     (else #f))))
              (q5(lambda(tape)
                   (printf "~a~n~a~n" (contents tape) 'q5)
                   (case (at tape)
                     ((a)(reconfig! tape)(q5 tape))
                     ((b)(reconfig! tape)(q5 tape))
                     (else #f))))
              (q6(lambda(tape)
                   (printf "~a~n~a~n" (contents tape) 'q6)
                   (case (at tape)
                     ((a)(reconfig! tape)(q5 tape))
                     ((b)(reconfig! tape)(q6 tape))
                     (($) #t)
                     (else #f)))))
             (let((t (read-only-tape)))
               (lambda(input)
                 (init! t input)
                 (eval (list ,start t)
                       (null-environment 5)))))
           (null-environment 5))))
  </code></pre>
  
  <p>I run it with</p>
  
  <pre><code>(run automaton 'q0 '(($)(a a b $)))
  </code></pre>
  
  <p>it's the text book's example.
  Is it ignoring the define code?</p>