问题
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
?
回答1:
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.
回答2:
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.
来源:https://stackoverflow.com/questions/32613416/implement-sicp-evaluator-using-racket