代码之家  ›  专栏  ›  技术社区  ›  rishi kant

如何在方案中实现put&get过程?

  •  2
  • rishi kant  · 技术社区  · 8 年前

    我在读书 sicp 书我被第2.4.3节卡住了, Data-Directed Programming and Additivity .

    如文中所述 收到 第3章(第3.3.3节)中给出了程序。但我没有找到这些程序,可能程序名称会有所不同。

    因此,当我尝试运行书中给出的代码(示例)时,repl抛出了一个错误,如下所示:

    1 ]=> (make-from-mag-ang 4 5)
    
    ;Unbound variable: get
    ;To continue, call RESTART with an option number:
    ; (RESTART 3) => Specify a value to use instead of get.
    ; (RESTART 2) => Define get to a given value.
    ; (RESTART 1) => Return to read-eval-print level 1.
    

    以下是代码:

    (define (attach-tag type-tag contents)
      (cons type-tag contents))
    
    (define (type-tag datum)
      (if (pair? datum)
        (car datum)
        (error "Bad tagged datum -- TYPE-TAG" datum)))
    
    (define (contents datum)
      (if (pair? datum)
        (cdr datum)
        (error "Bad tagged datum -- CONTENTS" datum)))
    
    (define (rectangular? z)
      (eq? (type-tag z) 'rectangular))
    
    (define (polar? z)
      (eq? (type-tag z) 'polar))
    
    
    (define (install-rectangular-package)
       ;; internal procedure
       (define (real-part z) (car z))
       (define (imag-part z) (cdr z))
       (define (magnitude z)
         (sqrt (+ (square (real-part z)) (square (imag-part z)))))
       (define (angle z)
         (atan (imag-part z) (real-part z)))
       (define (make-from-real-imag x y) (cons x y))
       (define (make-from-mag-ang r a)
         (cons (* r (cos a)) (* r (sin a))))
    
       ;; interface to the rest of the system
       (define (tag x) (attach-tag 'rectangular x))
       (put 'real-part '(rectangular) real-part)
       (put 'imag-part '(rectangular) imag-part)
       (put 'magnitude '(rectangular) magnitude)
       (put 'angle '(rectangular) angle)
       (put 'make-from-real-imag '(rectangular) (lambda (x y) (tag (make-from-real-imag x y))))
       (put 'make-from-mag-ang '(rectangular) (lambda (r a) (tag (make-from-mag-ang r a))))
       'done)
    
    
    (define (install-polar-package)
      ;; internal procedure
      (define (real-part z) (* (magnitude z) (cos (angle z))))
      (define (imag-part z) (* (magnitude z) (sin (angle z))))
      (define (magnitude z) (car z))
      (define (angle z) (cdr z))
      (define (make-from-real-imag x y)
        (cons (sqrt (+ (square x) (square y))) (atan y x)))
      (define (make-from-mag-ang r a) (cons r a))
    
      ;; interface to the rest of the system
      (define (tag x) (attach-tag 'polar x))
      (put 'real-part '(polar) real-part)
      (put 'imag-part '(polar) imag-part)
      (put 'magnitude '(polar) magnitude)
      (put 'angle '(polar) angle)
      (put 'make-from-real-imag '(polar) (lambda (x y) (tag (make-from-real-imag x y))))
      (put 'make-from-mag-ang '(polar) (lambda (r a) (tag (make-from-mag-ang r a))))
      'done)
    
    
    (define (apply-generic op . args)
      (let ((type-tags (map type-tag args)))
        (let ((proc (get op type-tags)))
          (if proc 
            (apply poc (map contents args))
            (error "No method for these types -- APPLY-GENERIC" (list op type-tags))))))
    
    (define (real-part z) (apply-generic 'real-part z))
    
    (define (imag-part z) (apply-generic 'imag-part z))
    
    (define (magnitude z) (apply-generic 'magnitude z))
    
    (define (angle z) (apply-generic 'angle z))
    
    (define (make-from-real-imag x y)
      ((get 'make-from-real-imag 'rectangular) x y))
    
    (define (make-from-mag-ang r a)
      ((get 'make-from-mag-ang 'polar) r a))
    

    谁能告诉我这些程序的实际执行情况,以便我在书中继续前进?任何帮助都将不胜感激。谢谢

    1 回复  |  直到 8 年前
        1
  •  6
  •   Flux    5 年前

    见本节 Representing Tables

    (define (make-table)
      (let ((local-table (list '*table*)))
        (define (lookup key-1 key-2)
          (let ((subtable (assoc key-1 (cdr local-table))))
            (if subtable
                (let ((record (assoc key-2 (cdr subtable))))
                  (if record
                      (cdr record)
                      false))
                false)))
        (define (insert! key-1 key-2 value)
          (let ((subtable (assoc key-1 (cdr local-table))))
            (if subtable
                (let ((record (assoc key-2 (cdr subtable))))
                  (if record
                      (set-cdr! record value)
                      (set-cdr! subtable
                                (cons (cons key-2 value)
                                      (cdr subtable)))))
                (set-cdr! local-table
                          (cons (list key-1
                                      (cons key-2 value))
                                (cdr local-table)))))
          'ok)    
        (define (dispatch m)
          (cond ((eq? m 'lookup-proc) lookup)
                ((eq? m 'insert-proc!) insert!)
                (else (error "Unknown operation - TABLE" m))))
        dispatch))
    
    (define operation-table (make-table))
    (define get (operation-table 'lookup-proc))
    (define put (operation-table 'insert-proc!))