我一直在尝试理解SICP中的数据导向编程,但到目前为止还不能理解.我对此有一些疑问。这是SICP的原始代码:
(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 (assoc key records)
(cond ((null? records) false)
((equal? key (caar records)) (car records))
(else (assoc key (cdr records)))))
(define operation-table (make-table))
(define get (operation-table 'lookup-proc))
(define put (operation-table 'insert-proc!))
(define (make-from-real-imag-rectangular x y)
(attach-tag 'rectangular (cons x y)))
(define (make-from-mag-ang-polar r a)
(attach-tag 'polar (cons r a)))
(define (make-from-real-imag x y)
(make-from-real-imag-rectangular x y))
(define (make-from-mag-ang r a)
(make-from-mag-ang-polar r a))
(define attach-tag cons)
(define type-tag car)
(define contents cdr)
(define (install-rectangular-package)
;;internal procedures
(define (real-part z)(car z))
(define (imag-part z)(cdr z))
(define (make-from-real-imag)(cons x y))
(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-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 procedures
(define (magnitude z) (car z))
(define (angle z) (cdr z))
(define (make-from-mag-ang r a) (cons r a))
(define (real-part z) (* (magnitude z) (cos (angle z))))
(define (imag-part z) (* (magnitude z) (sin (angle z))))
(define (make-from-real-imag x y)
(cons (sqrt (+ (square x) (square y)))
(atan y x)))
;; 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)
(install-polar-package)
(install-rectangular-package)首先,我不知道如何使用make-from real-imag或make-from mag-ang将条目放入表中。
(put 'make-from-real-imag 'rectangular
(lambda (x y) (tag (make-from-real-imag x y))))你能告诉我怎么叫这个程序才能准确地输入一个条目吗?
当我打电话给get而不放这样的条目时:
(get 'real-part '(rectangular))它返回(lambda (z) (car z))为什么?如果表中没有条目,或者我的代码有问题,它应该返回为false?
包内有“系统其他部分的接口”部分,在里面如何放置过程调用选择器(实参、映射部分、大小、角度)而没有任何争议?
(put 'real-part '(polar) real-part)发布于 2022-06-17 21:50:47
在我看过Brian的关于泛型操作符的cs61a第16课之后,我理解了一些数据定向编程。以下是布赖恩·哈维的cs61a第16课https://www.youtube.com/watch?v=zgbBNEuHs2w的youtube链接
当我们调用包时,过程会以lambda函数的形式放在表上。这就是为什么当我们调用(get 'real-part '(rectangular))时,它返回为(lambda (z) (car z))
因此,使用包调用put过程,例如(put 'real-part '(polar) real-part),该过程以(define (real-part z) (* (magnitude z) (cos (angle z))))作为参数,并将其作为表的条目。
这些程序是上述程序在书中的延续。
(define (map proc items)
(if (null? items)
nil
(cons (proc (car items))
(map proc (cdr items)))))
(define (apply-generic op . args)
(let ((type-tags (map type-tag args)))
(let ((proc (get op type-tags)))
(if proc
(apply proc (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)) 例如,要为矩形表示创建复数,我调用:
(define c-num1 (make-from-real-imag 5 3))现在我们有一个c-num1对象作为(rectangular 5 . 3)
我们可以用apply-generic调用该对象上的任何操作。
例如,(apply-generic 'real-part c-num1),我们得到5或(apply-generic 'imag-part c-num1),我们得到3,或者我们直接调用(real-part c-num1),它是用apply-generic定义的。
https://stackoverflow.com/questions/72590616
复制相似问题