首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >数据导向编程

数据导向编程
EN

Stack Overflow用户
提问于 2022-06-12 08:35:06
回答 1查看 120关注 0票数 2

我一直在尝试理解SICP中的数据导向编程,但到目前为止还不能理解.我对此有一些疑问。这是SICP的原始代码:

代码语言:javascript
复制
(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将条目放入表中。

代码语言:javascript
复制
(put 'make-from-real-imag 'rectangular
     (lambda (x y) (tag (make-from-real-imag x y))))

你能告诉我怎么叫这个程序才能准确地输入一个条目吗?

当我打电话给get而不放这样的条目时:

代码语言:javascript
复制
(get 'real-part '(rectangular))

它返回(lambda (z) (car z))为什么?如果表中没有条目,或者我的代码有问题,它应该返回为false?

包内有“系统其他部分的接口”部分,在里面如何放置过程调用选择器(实参、映射部分、大小、角度)而没有任何争议?

代码语言:javascript
复制
(put 'real-part '(polar) real-part)
EN

回答 1

Stack Overflow用户

发布于 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))))作为参数,并将其作为表的条目。

这些程序是上述程序在书中的延续。

代码语言:javascript
复制
(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)) 

例如,要为矩形表示创建复数,我调用:

代码语言:javascript
复制
(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定义的。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72590616

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档