博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
数据的过程性表示
阅读量:6328 次
发布时间:2019-06-22

本文共 2110 字,大约阅读时间需要 7 分钟。

夜里睡不着看起了 SICP,这里是第二章《构造数据抽象》的笔记。

知识点一:序对

(cons x y) 表示一个序对,记为 z。(car z) 可以获取 z 的第一个元素 x。(cdr z) 可以获取 z 的第二个元素 y。复制代码

cons(读作控死)、car(读作卡) 和 cdr(读作酷得儿)

翻译成 JS 风格的伪代码就是

z = cons x ycar z // 值为 xcdr z // 值为 y复制代码

知识点二:数据的过程性表示

有没有可能 cons、car 和 cdr 其实是三个过程(也就是函数)呢?

只要 cons、car 和 cdr 三个函数满足上面的要求即可,下面是这三个函数的写法:

(define (cons x y)  (define (dispatch m)    (cond ((= m 0) x)          ((= m 1) y)          (else (error "argument not 0 or 1 -- cons" m))))  despatch)(define (car z) (z 0))(define (cdr z) (z 1))复制代码

翻译成 JS 大概是这样的:

function cons(x, y){  // 直接返回一个函数  return function dispatch(m){    if(m===0){
return x} if(m===1){
return y} throw new Error('argument not 0 or 1 -- cons' + m) }}function car(z){ return z(0)}function cdr(z){ return z(1)}复制代码

这里令人惊奇的地方就在于 cons 直接返回了一个函数,并没有返回一个数组之类的玩意。

不过这只是一种模拟,语言内部并不是这样实现的。这种程序设计风格叫做「消息传递」。

知识点三

还可以这样定义 cons、car、cdr

(define (cons x y)  (lambda (m) (m x y)))(define (car z)  (z (lambda (a b) a)))(define (cdr z)  (z (lambda (a b) b))复制代码

翻译成 JS 是这样

cons = (x, y)=> {  return (m) => m(x, y)}car = z => {  return z((a, b) => a)}cdr = z => {  return z((a, b) => b)}复制代码

写成这样还挺烧脑的。

知识点四

上面的知识点说明其实可以抛弃复合数据结构,全用函数就行了。

但是如果我告诉你,连数字都可以不需要呢?(假设只考虑非负整数,而且这种语言允许我们对函数进行任何操作)

0 用一个函数来表示

zero = f => x => x // 这里的 f 看起来没有意义,要到下面才能理解复制代码

加1操作用另一个函数来表示

add1 = n => f => x => f(n(f)(x))复制代码

1、2 的表示方法见。

zero= f => x => xone = f => x => f(x)two = f => x => f(f(x))复制代码

这样定义了之后,可以证明

add1(zero) 得到的函数跟 one 是一模一样的(但不是同一个函数);

add1(one) 得到的函数跟 two 是一模一样的(但不是同一个函数);

虽然我不知道这样做有什么意义,不过还是很震撼的。

知识点五:cons 的闭包性质(与 JS 的闭包不是同一个术语)

一般来说,某种组合数据对象的操作满足闭包性质是指:通过它组合起数据对象得到的结果本身还可以通过同样的操作再进行组合。

换句话说:组合式的成员本身还可以是组合式的。

比如

(const (cons 1 2)        (cons 3 4))复制代码

cons 组合 1、2 得到的数据,还可以作为 cons 的元素,所以说 cons 满足闭包性质。

知识点六:链表

(cons 1   (cons 2 (    cons 3 (      cons 4 nil))))复制代码

通过 cons 的这种性质,很容易用 cons 表示一个链表。

这种语法可以简化为

(list 1 2 3 4)复制代码

注意 (list 1 2 3 4) 是一个函数调用,其返回值为(1 2 3 4)。假设 one-to-four = (list 1 2 3 4)

(define one-to-four (list 1 2 3 4))复制代码

car one-to-four 就是获取表头,cdr one-to-four 就是获取表头之外的节点。

我们可以用 cons 来在链表中插入节点

(cons 10 one-to-four)复制代码

结果为(10 1 2 3 4)。

还挺有意思的。

未完待续……

第三章的笔记:

转载地址:http://gywoa.baihongyu.com/

你可能感兴趣的文章
关于raid的基本原理、软raid的实现演示
查看>>
科技企业的幕后推手,人工智能究竟有何魔力
查看>>
详解Oracle临时表的几种用法及意义
查看>>
HTML(七)------ 表格
查看>>
如何成为一个设计师和程序员混合型人才
查看>>
unable to load selinux policy. machine is in enforcing
查看>>
2015年10月23日作业
查看>>
MySQL5.7 加强了root用户登录安全性
查看>>
CentOS 6.3_Nagios安装配置与登录
查看>>
加强型的记录集权限(数据集权限、约束表达式设置功能)实现方法界面参考...
查看>>
Linux 内存机制
查看>>
linux下定时任务
查看>>
SharePoint 2013 部署 Part 1
查看>>
DWGSee看图纸dwg文件阅读器免费下载地址
查看>>
高能天气——团队Scrum冲刺阶段-Day 1-领航
查看>>
ISI CVPR journal ranking
查看>>
free movie
查看>>
列表组
查看>>
CF 988E Divisibility by 25 思维 第十二
查看>>
Linux Shell多命令执行
查看>>