2

I am implementing circular evaluator in Chapter 4 SICP with racket, it seems that the code running fine only it cannot add new frames to the environment due to set-car! issue.

I tried the followings:

  1. add the definitions into the code. The set-car! is defined in the previous chapter in SICP as follows:
(define (cons x y)
    (define (set-x! v) (set! x v))
    (define (set-y! v) (set! y v))
    (define (dispatch m)
        (cond ((eq? m 'car) x)
                      ((eq? m 'cdr) y)
                      ((eq? m 'set-car!) set-x!)
                      ((eq? m 'set-cdr!) set-y!)
                      (else
            (error "Undefined operation: CONS" m))))
    dispatch)
(define (car z) (z 'car))
(define (cdr z) (z 'cdr))
(define (set-car! z new-value)
    ((z 'set-car!) new-value) z)
(define (set-cdr! z new-value)
    ((z 'set-cdr!) new-value) z)

however, it reports error, because the definition primitive-procedures in the evaluator still use tradition definitions of list as shown below, which is incompatible with new definition of cons as dispatch precedure, thus cannot fetched by car, cdretc.

(define primitive-procedures
  (list (cons 'car car) 
        (cons 'cdr cdr)
        (cons 'cons cons)
        (cons 'null? null?)
       ; <more primitives> 
        ))
  1. I renamed the definitions of cons etc. to mcons, mcar, mcdr,etc.
(define (mcons x y)
    (define (set-x! v) (set! x v))
    (define (set-y! v) (set! y v))
    (define (dispatch m)
        (cond ((eq? m 'car) x)
                      ((eq? m 'cdr) y)
                      ((eq? m 'set-car!) set-x!)
                      ((eq? m 'set-cdr!) set-y!)
                      (else
            (error "Undefined operation: CONS" m))))
    dispatch)
(define (mcar z) (z 'car))
(define (mcdr z) (z 'cdr))
(define (set-car! z new-value)
    ((z 'set-car!) new-value) z)
(define (set-cdr! z new-value)
    ((z 'set-cdr!) new-value) z)

but, it still reports error, for the same reason as 1. primitive-procedures still use build-in version of cons.

  1. according to Rahn's answer, I add the following code:
(require (only-in (combine-in rnrs/base-6
                              rnrs/mutable-pairs-6)
                  set-car!
                  set-cdr!))

but again, it reports error:

set-mcar!: contract violation
  expected: mpair?
  given: '((car cdr cons null?) (primitive #<procedure:car>) (primitive #<procedure:cdr>) (primitive #<procedure:cons>) (primitive #<procedure:null?>))

It seems SICP use set-car! frequently throughout the book, but it also use traditional definitions of cons such as cadr at the same time, which is quite confusing (when running with racket).

Any suggestions with the set-car! issue will be gratefully appreciated.

8
  • 2
    Are you using the sicp language package? Commented Nov 9 at 7:06
  • no, for now I am trying to do everything by myself. I haven't heard about it, I will look into it now. Thank you very much. Commented Nov 9 at 9:38
  • 1
    After installing the sicp package, it works now! It is just I still not quite clear about how the problem is solved, is that possible that you could kindly provide more details please? Thank you very much. Commented Nov 9 at 10:02
  • Normal Racket has immutable cons cells and thus no set-car! etc. The sicp lang (and others that are traditionally Schemey) use mutable mcons cells instead and import renamed copies of set-mcar! etc. Commented Nov 10 at 0:27
  • There are probably existing questions that explain it that this one is a dupe of but I'm too lazy to dig one up right now. Commented Nov 10 at 0:33

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.