2008-12-24 60 views
3

我有一个长期项目正在通过SICP的所有练习。我注意到最近的练习有点奇怪。我正在测试霍夫曼编码树。当我在DrScheme执行下面的代码我得到预期的结果:DrScheme与mzscheme:治疗定义

(a d a b b c a) 

但是,如果我通过调用(载“2.67.scm”)或者通过运行的MzScheme -f 2.67.scm执行中的MzScheme相同的代码它报告:

symbols: expected symbols as arguments, given: (leaf D 1) 

我的问题是:为什么?是否因为mzscheme和drscheme使用不同的规则来加载程序定义?程序代码如下。

;; Define an encoding tree and a sample message 
;; Use the decode procedure to decode the message, and give the result. 

(define (make-leaf symbol weight) 
    (list 'leaf symbol weight)) 
(define (leaf? object) 
    (eq? (car object) 'leaf)) 
(define (symbol-leaf x) (cadr x)) 
(define (weight-leaf x) (caddr x)) 

(define (make-code-tree left right) 
    (list left 
     right 
     (append (symbols left) (symbols right)) 
     (+ (weight left) (weight right)))) 

(define (left-branch tree) (car tree)) 
(define (right-branch tree) (cadr tree)) 

(define (symbols tree) 
    (if (leaf? tree) 
     (list (symbol-leaf tree)) 
     (caddr tree))) 
(define (weight tree) 
    (if (leaf? tree) 
     (weight-leaf tree) 
     (cadddr tree))) 

(define (decode bits tree) 
    (define (decode-1 bits current-branch) 
    (if (null? bits) 
     '() 
     (let ((next-branch 
       (choose-branch (car bits) current-branch))) 
      (if (leaf? next-branch) 
       (cons (symbol-leaf next-branch) 
        (decode-1 (cdr bits) tree)) 
       (decode-1 (cdr bits) next-branch))))) 
    (decode-1 bits tree)) 
(define (choose-branch bit branch) 
    (cond ((= bit 0) (left-branch branch)) 
     ((= bit 1) (right-branch branch)) 
     (else (error "bad bit -- CHOOSE-BRANCH" bit)))) 

(define (test s-exp) 
    (display s-exp) 
    (newline)) 

(define sample-tree 
    (make-code-tree (make-leaf 'A 4) 
        (make-code-tree 
        (make-leaf 'B 2) 
        (make-code-tree (make-leaf 'D 1) 
            (make-leaf 'C 1))))) 

(define sample-message '(0 1 1 0 0 1 0 1 0 1 1 1 0)) 

(test (decode sample-message sample-tree)) 

回答

6

默认情况下,才能使用MzScheme开始在那里是symbols现有定义一个模式,它内联它所知道的功能 - 所以当它编译你的make-code-tree定义,它使用它知道的结合。当它稍后编译你的symbols时,它对先前的定义没有影响。

处理此问题的最简单方法是将代码放入模块中,前缀为#lang scheme