SICP读书笔记 2.4
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>)
- 首先是先安装操作包
(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)
- 还是需要进行类型分派
(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的更多相关文章
- 【SICP读书笔记(一)】正则序展开的特殊情况
scheme解释器有两种实现方式,一种是应用序,先对每个参数求值,再以首过程对所有求得的参数求值. 第二种是正则序,会“完全展开然后归约”(书中原文) SICP中的练习1.5,让我困惑了一下.原题如下 ...
- SICP读书笔记 1.1
SICP CONCLUSION 让我们举起杯,祝福那些将他们的思想镶嵌在重重括号之间的Lisp程序员 ! 祝我能够突破层层代码,找到住在里计算机的神灵! 目录 1. 构造过程抽象 2. 构造数据抽象 ...
- SICP读书笔记 3.5
SICP CONCLUSION 让我们举起杯,祝福那些将他们的思想镶嵌在重重括号之间的Lisp程序员 ! 祝我能够突破层层代码,找到住在里计算机的神灵! 目录 1. 构造过程抽象 2. 构造数据抽象 ...
- SICP读书笔记 3.4
SICP CONCLUSION 让我们举起杯,祝福那些将他们的思想镶嵌在重重括号之间的Lisp程序员 ! 祝我能够突破层层代码,找到住在里计算机的神灵! 目录 1. 构造过程抽象 2. 构造数据抽象 ...
- SICP读书笔记 3.2
SICP CONCLUSION 让我们举起杯,祝福那些将他们的思想镶嵌在重重括号之间的Lisp程序员 ! 祝我能够突破层层代码,找到住在里计算机的神灵! 目录 1. 构造过程抽象 2. 构造数据抽象 ...
- SICP读书笔记 3.3
SICP CONCLUSION 让我们举起杯,祝福那些将他们的思想镶嵌在重重括号之间的Lisp程序员 ! 祝我能够突破层层代码,找到住在里计算机的神灵! 目录 1. 构造过程抽象 2. 构造数据抽象 ...
- SICP读书笔记 3.1
SICP CONCLUSION 让我们举起杯,祝福那些将他们的思想镶嵌在重重括号之间的Lisp程序员 ! 祝我能够突破层层代码,找到住在里计算机的神灵! 目录 1. 构造过程抽象 2. 构造数据抽象 ...
- SICP读书笔记 2.5
SICP CONCLUSION 让我们举起杯,祝福那些将他们的思想镶嵌在重重括号之间的Lisp程序员 ! 祝我能够突破层层代码,找到住在里计算机的神灵! 目录 1. 构造过程抽象 2. 构造数据抽象 ...
- SICP读书笔记 2.3
SICP CONCLUSION 让我们举起杯,祝福那些将他们的思想镶嵌在重重括号之间的Lisp程序员 ! 祝我能够突破层层代码,找到住在里计算机的神灵! 目录 1. 构造过程抽象 2. 构造数据抽象 ...
随机推荐
- 1202. [HNOI2005]狡猾的商人【贪心 或 并查集】
Description 刁姹接到一个任务,为税务部门调查一位商人的账本,看看账本是不是伪造的.账本上记录了n个月以来的收入情况,其中第i 个月的收入额为Ai(i=1,2,3...n-1,n), .当 ...
- Java基础加强之代理
本文引用自 http://www.cnblogs.com/xdp-gacl/p/3971367.html 1.什么是代理 动态代理技术是整个java技术中最重要的一个技术,它是学习java框架的基础, ...
- flex使用学习
1.指定容器为flex布局 display:flex 行内元素也可以使用Flex布局. display: inline-flex; 注意,设为Flex布局以后,子元素的float.clear和vert ...
- Jenkins+Github(Robotframework代码)
个人记录,且为Windows10系统,仅供参考. 一. 准备 1. Github:安装git.注册github.将Robotframework代码更新到github. 2. Jenkins安装,并安装 ...
- kaggle _Titanic: Machine Learning from Disaster
A Data Science Framework: To Achieve 99% Accuracy https://www.kaggle.com/ldfreeman3/a-data-science-f ...
- css笔记--用户界面样式
1.系统字体,系统颜色.根据关键字设置为系统某方面相同的字体和颜色 2.光标:鼠标移入时光标的不同显示方法,有十字键,手型:cursor:pointer;cursor:hand;要按顺序,cursor ...
- oracle 子查询 where having from ,from子查询提高效率
where 子查询主要功能是控制数据行的,返回结果一般都是单行单列.多行单列.单行多列数据 单行单列 SELECT * FROM emp WHERE hiredate=( SELECT MIN(hir ...
- ios应用数据存储方式(XML属性列表-plist) - 转
一.ios应用常用的数据存储方式 1.plist(XML属性列表归档) 2.偏好设置 3.NSKeydeArchiver归档(存储自定义对象) 4.SQLite3(数据库,关系型数据库,不能直 ...
- 面向对象之this关键字
方法之间调用,可以通过方法名进行调用.但构造方法,无法通过构造方法名来相互调用. 构造方法之间的调用,可以通过this关键字来完成. l 构造方法调用格式: this(参数列表); l 构造方法的 ...
- 远程连接服务器端Jupyter Notebook
1. 安装 输入命令: sudo apt-get install sshfs 2. 服务器端开启Jupyter Notebook Ubuntu服务器端安装过程参考:www.cnblogs.com/la ...