SICP CONCLUSION

让我们举起杯,祝福那些将他们的思想镶嵌在重重括号之间的Lisp程序员 !

祝我能够突破层层代码,找到住在里计算机的神灵!

目录

1. 构造过程抽象
2. 构造数据抽象
3. 模块化、对象和状态
4. 元语言抽象
5. 寄存器机器里的计算

Chapter 2

  • 构造数据对象
练习答案

抽象数据的多重表示

在这一节里,我们将学习如何去处理数据,是他们可能在一个程序的不同部分中采用不同的表示方式。这就需要我们去构造通用型过程

复数的表示

复数有两种不一样的表示方式,也同样更合适不一样的操作

而重要的是,如何让这两种表示方式共存一个系统,并能够在合适的地方调用合适的方法

带标识数据

可以将数据抽象看作为“最小允诺原则”的一个应用

如何使两种不同的表示方法共存一个系统的方法就是使用类型标识,在构造数据时为不同表示方式加上类型标识,在进行操作时,根据不同的操作,剖去标识选择合适的操作

;; Ben (rectangular)

(define (real-part-rectangular z) (car z))

(define (imag-part-rectangular z) (cdr z))

(define (magnitude-rectangular z)
(sqrt (+ (square (real-part-rectangular z))
(square (imag-part-rectangular z))))) (define (angle-rectangular z)
(atan (imag-part-rectangular z)
(real-part-rectangular z))) (define (make-from-real-imag-rectangular x y)
(attach-tag 'rectangular (cons x y))) (define (make-from-mag-ang-rectangular r a)
(attach-tag 'rectangular
(cons (* r (cos a)) (* r (sin a))))) ;; Alyssa (polar) (define (real-part-polar z)
(* (magnitude-polar z) (cos (angle-polar z)))) (define (imag-part-polar z)
(* (magnitude-polar z) (sin (angle-polar z)))) (define (magnitude-polar z) (car z)) (define (angle-polar z) (cdr z)) (define (make-from-real-imag-polar x y)
(attach-tag 'polar
(cons (sqrt (+ (square x) (square y)))
(atan y x)))) (define (make-from-mag-ang-polar r a)
(attach-tag 'polar (cons r a))) ;; Generic selectors (define (real-part z)
(cond ((rectangular? z)
(real-part-rectangular (contents z)))
((polar? z)
(real-part-polar (contents z)))
(else (error "Unknown type -- REAL-PART" z)))) (define (imag-part z)
(cond ((rectangular? z)
(imag-part-rectangular (contents z)))
((polar? z)
(imag-part-polar (contents z)))
(else (error "Unknown type -- IMAG-PART" z)))) (define (magnitude z)
(cond ((rectangular? z)
(magnitude-rectangular (contents z)))
((polar? z)
(magnitude-polar (contents z)))
(else (error "Unknown type -- MAGNITUDE" z)))) (define (angle z)
(cond ((rectangular? z)
(angle-rectangular (contents z)))
((polar? z)
(angle-polar (contents z)))
(else (error "Unknown type -- ANGLE" z))))

数据导向的程序设计和可加性

在上面的标识类型最大的问题就是不具备可加性,当我需要再加入另外一种表示方式的时候,我就需要修改类型分派的所以地方,第二不是不允许重名

这时就引进了一种新技术:数据导向。我们以一种具有操作名字,数据类型,实际过程为信息的表格为基础。其中所有的操作都应该到这个表格中查询,所以再增加新操作时也只需要像表格中加入信息。

操作表格:

(put <op><type><item>)

(get <op><type>)

  1. 首先是先安装操作包
(define (install-rectangular-package)
;; internal procedures
(define (real-part z) (car z))
(define (imag-part z) (cdr z))
(define (make-from-real-imag x y) (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)
  1. 还是需要进行类型分派
(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)))))) ;; Generic selectors (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)
(define (dispatch op)
(cond ((eq? op 'real-part) x)
((eq? op 'imag-part) y)
((eq? op 'magnitude)
(sqrt (+ (square x) (square y))))
((eq? op 'angle) (atan y x))
(else
(error "Unknown op -- MAKE-FROM-REAL-IMAG" op))))
dispatch) (define (apply-generic op arg) (arg op))

这一小节或许已经能够体现这本书为什么会被人誉为圣经,层层深入,思想毫不过时。这一节里在数据抽象里更深入一层,虽然我们不管数据底层如何实现,但是如果在底层的实现里我们需要更加灵活更加通用又要怎么做呢?书里提到几种技术,类型标识,数据导向,消息传递,而其中所谓的数据导向会不会是在面向对象语言里实现重载的方法呢?而消息传递或许也是面向对象的雏形吧。所以在这更加之上的是,它们都是为了更加通用的系统的目标

SICP读书笔记 2.4的更多相关文章

  1. 【SICP读书笔记(一)】正则序展开的特殊情况

    scheme解释器有两种实现方式,一种是应用序,先对每个参数求值,再以首过程对所有求得的参数求值. 第二种是正则序,会“完全展开然后归约”(书中原文) SICP中的练习1.5,让我困惑了一下.原题如下 ...

  2. SICP读书笔记 1.1

    SICP CONCLUSION 让我们举起杯,祝福那些将他们的思想镶嵌在重重括号之间的Lisp程序员 ! 祝我能够突破层层代码,找到住在里计算机的神灵! 目录 1. 构造过程抽象 2. 构造数据抽象 ...

  3. SICP读书笔记 3.5

    SICP CONCLUSION 让我们举起杯,祝福那些将他们的思想镶嵌在重重括号之间的Lisp程序员 ! 祝我能够突破层层代码,找到住在里计算机的神灵! 目录 1. 构造过程抽象 2. 构造数据抽象 ...

  4. SICP读书笔记 3.4

    SICP CONCLUSION 让我们举起杯,祝福那些将他们的思想镶嵌在重重括号之间的Lisp程序员 ! 祝我能够突破层层代码,找到住在里计算机的神灵! 目录 1. 构造过程抽象 2. 构造数据抽象 ...

  5. SICP读书笔记 3.2

    SICP CONCLUSION 让我们举起杯,祝福那些将他们的思想镶嵌在重重括号之间的Lisp程序员 ! 祝我能够突破层层代码,找到住在里计算机的神灵! 目录 1. 构造过程抽象 2. 构造数据抽象 ...

  6. SICP读书笔记 3.3

    SICP CONCLUSION 让我们举起杯,祝福那些将他们的思想镶嵌在重重括号之间的Lisp程序员 ! 祝我能够突破层层代码,找到住在里计算机的神灵! 目录 1. 构造过程抽象 2. 构造数据抽象 ...

  7. SICP读书笔记 3.1

    SICP CONCLUSION 让我们举起杯,祝福那些将他们的思想镶嵌在重重括号之间的Lisp程序员 ! 祝我能够突破层层代码,找到住在里计算机的神灵! 目录 1. 构造过程抽象 2. 构造数据抽象 ...

  8. SICP读书笔记 2.5

    SICP CONCLUSION 让我们举起杯,祝福那些将他们的思想镶嵌在重重括号之间的Lisp程序员 ! 祝我能够突破层层代码,找到住在里计算机的神灵! 目录 1. 构造过程抽象 2. 构造数据抽象 ...

  9. SICP读书笔记 2.3

    SICP CONCLUSION 让我们举起杯,祝福那些将他们的思想镶嵌在重重括号之间的Lisp程序员 ! 祝我能够突破层层代码,找到住在里计算机的神灵! 目录 1. 构造过程抽象 2. 构造数据抽象 ...

随机推荐

  1. 集合之subList的缺陷

    我们经常使用subString方法来对String对象进行分割处理,同时我们也可以使用subList.subMap.subSet来对List.Map.Set进行分割处理,但是这个分割存在某些瑕疵. 一 ...

  2. [转] Eclipse安装SVN插件

    eclipse里安装SVN插件,一般来说,有三种方式: 1. 直接下载SVN插件,将其解压到eclipse的对应目录里 2. 使用eclipse 里Help菜单的“Install New Softwa ...

  3. sqoop数据导入命令 (sql---hdfs)

    mysql------->hdfs sqoop导入数据工作流程: sqoop提交任务到hadoop------>hadoop启动mapreduce------->mapreduce通 ...

  4. CentOS中配置xrdp,通过微软远程桌面访问CentOS桌面

    环境:CentOS 6.4 1.安装相关软件 yum groupinstall "Desktop" (已安装桌面的就可以缺略这条命令) yum install xrdp yum i ...

  5. 12 Bit ADC与LSB的含义

    [转]12 Bit ADC与LSB的含义 LSB(Least Significant Bit),意为最低有效位:MSB(Most Significant Bit),意为最高有效位,若MSB=1,则表示 ...

  6. member access within misaligned address 0x0000002c3931 for type 'struct ListNode‘

    From MWeb 在做leetcode 第2题时使用C语言编写链表时报错 错误复现 错误原因 解决办法 错误复现 报错时的代码如下 /** * Definition for singly-linke ...

  7. 《Arduino 机器人制作指南》唐乐 分享 pdf下载

    链接:https://pan.baidu.com/s/1cF7gaQoJXwfY0asnsimFrQ提取码:stq1

  8. git更新远程仓库报错

    hint: Updates were rejected because the tip of your current branch is behind hint: its remote counte ...

  9. d3 js emberjs handlerbarjs

    http://handlebarsjs.com/ http://emberjs.com/ http://jsbin.com/d3ember-barchart/13/edit?html,output

  10. 20155327预备作业3:Linux安装及命令入门

    20155327预备作业3:Linux安装及命令入门 安装Linux操作系统 由于之前安装过所以这里就不再赘述了 掌握Linux命令的学习方法 学习路径: 常用Ubuntu快捷键: CTRL+ALT+ ...