1

I'm working on metacircular evaluator of 4.1.4 Running the Evaluator as a Program, building which with Racket:

#lang racket

(require (combine-in rnrs/base-6
                     rnrs/mutable-pairs-6))

(define (evaluate exp)
  (cond 
    ; ...
    ((definition? exp) (display exp)
                       (display " is a definition\n"))
    ; ...
    (else (display exp) 
          (display " is something else\n"))))

(define (definition? exp)
  (tagged-list? exp 'define))

(define (tagged-list? exp tag)
  (if (pair? exp)
      (eq? (car exp) tag)
      false))

(define (driver-loop)
  (let ((input (read)))
    (let ((output (evaluate input)))
      output))
  (driver-loop))

(driver-loop)

After getting a box that reads input in DrRacket successfully, I type in (define a 0) and it turn out:

(define a 0) is something else

It could be recognised if I remove

(require (combine-in rnrs/base-6
                     rnrs/mutable-pairs-6))

But without which I wouldn't be able to call set-car! or set-cdr!. Is there an alternative for set- function?

Or could I choose what to import from rnrs/base-6 and rnrs/mutable-pairs-6 ?

Rahn
  • 4,787
  • 4
  • 31
  • 57
  • Does expressions other then definitions work? If so, add the definition of `definition?` as it must be the problem. – Kevin Sep 16 '15 at 16:26
  • How exactly did you call `eval`? I mean, how did you pass the parameters – Óscar López Sep 16 '15 at 16:42
  • @Rahn The problem does not lie in `definition?`. I made a quick test that evals the result of `read` and it succesfully recognizes the expression as a definition. Hence the problem must be how you are calling `eval`. The `exp` argument must be different from the result of `(read)`, else it would work. – Kevin Sep 16 '15 at 16:45
  • @ÓscarLópez `eval` added in. – Rahn Sep 17 '15 at 00:18
  • @HyperZ `eval` added in. – Rahn Sep 17 '15 at 00:18

2 Answers2

0

It should run fine. I made a quick test with the code you gave.

(define (evaluate exp)
  (cond 
    ; ...
    ((definition? exp) (display exp)
                       (display " is a definition\n"))
    ; ...
    (else (display exp) 
          (display " is something else\n"))))

(define (definition? exp)
  (tagged-list? exp 'define))

(define (tagged-list? exp tag)
  (if (pair? exp)
      (eq? (car exp) tag)
      false))

(define (driver-loop)
  (let ((input (read)))
    (let ((output (evaluate input)))
      output))
  (driver-loop))

(driver-loop)

Running this in the racket language will give me :

--> is user input
-->(define a 0)
   (define a 0) is a definition
-->(list 1 2 3)
   (list 1 2 3) is something else

As you can see the right branch of the conditional was entered.

Are you sure the error comes from the else branch? Because your error message contains a :, display in the else branch don't.

EDIT : What exactly did you entered in the input prompt? Confusion could be that a call to Racket's eval function needs a list as argument, (eval '(define a 0)). However if you enter this in the input prompt it won't work. You'll have to write (define a 0), like a normal definition.

Kevin
  • 2,813
  • 3
  • 20
  • 30
0

Here is the bug:

(require (combine-in rnrs/base-6
                     rnrs/mutable-pairs-6))

Package rnrs/base-6 and rnrs/mutable-pairs-6 bring in something unpredicted that change cons(as well as car, cdr) leading (define a 0) not been caught by definition?

Solution:

(require (only-in (combine-in rnrs/base-6
                              rnrs/mutable-pairs-6)
                  set-car!
                  set-cdr!))

Always put only-in in require to avoid any unwanted binding.

Rahn
  • 4,787
  • 4
  • 31
  • 57