the little schemer 笔记(6)

第六章 Shadows

1 是算术表达式吗

3 是算术表达式吗

是的

1+3 是算术表达式吗

是的

1+3×4 是算术表达式吗

当然是

cookie 是算术表达式吗

是啊,你需要来一块吗

e那么 3 ^ y + 5

是的

你来说说什么是算术表达式

我们这样描述
“对于这一章,算术表达式可以是atom原子(包括数),或者由+,×,或者^连接的两个算术表达式。”

(quote a) 是什么

a

(quote +) 是什么

原子+,而不是操作+

(quote ×) 代表什么

代表原子×,而不是操作×

(eq? (quote a) y) 是真还是假,其中y是a

(eq? x y) 是真还是假,其中x是a,y是a

者痛前边的那个问题一样。真。

(n + 3) 是算术表达式吗

不是啊,括号括着 n + 3。我们的算术定义没有提到括号。

我们可以认为(n + 3) 是算术表达式吗吗

可以,只要注意括号问题。(原文没看明白:Yes, if we keep in mind that the parentheses are not really there.)

那(n + 3)怎么称呼

称作(n + 3)的表达(representation)

为什么(n + 3) 是一个好的表达

因为
1.  (n + 3) 是一个 S-expression表达式,它可以作为函数参数
2.  它就像 n + 3

(numbered? x)是真还是假,其中x是 1

3 + 4 × 5 的表示是什么

(3 + (4 × 5))

(numbered? y) 是真还是假,其中y是(3 + (4 ^ 5))

(numbered? z) 是真还是假,其中z是(2 × sausage)

假,因为sausage不是一个数。

numbered?是什么

一个函数,查询一个算术表示是否只包含有在+,×,和^,及其后边的数。

写个 numbered?函数的框架试试

(define numbered?
  (lambda (aexp)
    (cond
      (_____ _____)
      (_____ _____)
      (_____ _____)
      (_____ _____))))

第一个查询是什么

(atom? aexp)

(eq? (car (cdr aexp)) (quote +))是什么

这是第二个查询

你能猜出来第三个查询吗

(eq? (car (cdr aexp)) (quote ×)),完全正确

那第四个查询呢

(eq? (car (cdr aexp)) (quote ^)),完全正确

我们还需要查询aexp吗

不需要了,我们可以用else把前一个查询替换掉

为什么我们查询算术表达式是四个,而不是两个。毕竟像(1 + 3)这样的算术表达式是lats(即原子构成的list表)

因为我们把(1 + 3)表达看作是lsit表组成的算术表达式,而不是它本身的那样。而且算术表达式可以是数,或者有算术表达式和+,×,或者^连接组成。

现在你能写出函数 numbered?吗

(define (atom? x)
  (and (not (null? x))
       (not (pair? x))))

(define numbered?
  (lambda (aexp)
    (cond
      ((atom? aexp) (number? aexp))
      ((eq? (car (cdr aexp)) (quote +)) ...)
      ((eq? (car (cdr aexp)) (quote ×)) ...)
      ((eq? (car (cdr aexp)) (quote ^)) ...))))

为什么当aexp是atom原子时查询(number? aexp)

因为我们想知道算术表达式中的原子是否是数

为什么我们需要知道是否aexp中+连接的东西是否是两个算术表达式

我们需要查找出来两个子表达式是否是numbered

第一个 subsexpression在哪儿

就是aexp的car

第二个 subsexpression在哪儿

就是aexp的cdr的cdr的car(即aexp的第三个成员)

所以我们需要查询什么

(numbered? (car aexp))和(numbered? (car (cdr (cdr aexp))))必须都是真。

第二个回答是什么

(and (numbered? (car aexp)) (numbered? (car (cdr (cdr aexp)))))

再试试写出函数 numbered?

(define (atom? x)
  (and (not (null? x))
       (not (pair? x))))

(define numbered?
  (lambda (aexp)
    (cond
      ((atom? aexp) (number? aexp))
      ((eq? (car (cdr aexp)) (quote +)) (and (numbered? (car aexp)) (numbered? (car (cdr (cdr aexp))))))
      ((eq? (car (cdr aexp)) (quote ×)) (and (numbered? (car aexp)) (numbered? (car (cdr (cdr aexp))))))
      ((eq? (car (cdr aexp)) (quote ^)) (and (numbered? (car aexp)) (numbered? (car (cdr (cdr aexp)))))))))

既然aexp已经被认为是算术表达式,我们可以把 numbered?写得更简单些

(define (atom? x)
  (and (not (null? x))
       (not (pair? x))))

(define numbered?
  (lambda (aexp)
    (cond
      ((atom? aexp) (number? aexp))
      (else (and (numbered? (car aexp)) (numbered? (car (cdr (cdr aexp)))))))))

为什么可以简化

因为我们知道函数是正确的

(value u) 的值是多少,其中u是13

13

(value x) 的值是多少,其中x是(1 + 3)

4

(value y) 的值是多少,其中x是(1 + (3 ^ 4))

(value z) 的值是多少,其中z是cookie

没有答案

(value nexp) 返回我们认为的那样的数学算术表达式的值

期待如此

value 对nexp要几个查询

4个

现在,让我们试着写出函数 value

(define value
  (lambda (nexp)
    (cond
      ((atom? nexp) ...)
      ((eq? (car (cdr nexp)) (quote +)) ...)
      ((eq? (car (cdr nexp)) (quote ×)) ...)
      (else ...))))

由+把两个算术表达式相连而构成的算术表达式的值是多少

如果我们知道两个子表达式的值,我们把它们求和就可以了。

(1 + (3 × 4)中的里那哥哥子表达式的值是什么

当然是用value计算1,再用value计算(3 × 4)就可以了

总的来说呢

在子表达式上递归value

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
第七戒
在相同本性的东西上递归子组成部分:
*list表
*算术表达式
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

再试试函数value

(define value
  (lambda (nexp)
    (cond
      ((atom? nexp) nexp)
      ((eq? (car (cdr nexp)) (quote +)) (+ (value (car nexp)) (car (cdr (cdr nexp)))))
      ((eq? (car (cdr nexp)) (quote ×)) ('× (value (car nexp)) (car (cdr (cdr nexp)))))
      (else ('^ (value (car nexp)) (car (cdr (cdr nexp))))))))

你能想出算术表达式的不同表示吗

有好几种呢

(3 4 +)可以表示 3 + 4吗

可以啊

(+ 3 4) 可以吗

可以吗

或者(plus 3 4)

可以

(+ ( 3 6) (^ 8 2))是一个算术表达式的表达吗

是的。

试着谢谢函数value来处理一种新的算术表达式,可以是:
——是数
——是 + 后边跟着两个算术表达式
——是 × 后边跟着两个算术表达式
——是 ^ 后边跟着两个算术表达式

这个怎么样

(define value
  (lambda (nexp)
    (cond
      ((atom? nexp) nexp)
      ((eq? (car nexp) (quote +)) (+ (value (cdr nexp)) (car (cdr (cdr nexp)))))
      ((eq? (car nexp) (quote ×)) (× (value (cdr nexp)) (car (cdr (cdr nexp)))))
      (else (^ (value (cdr nexp)) (car (cdr (cdr nexp))))))))

你猜的没错

这个是错的

让我们试一试
(+ 1 3)

(atom ? nexp),其中 nexp 是(+ 1 3)

(eq? (car nexp) (quote +)) 其中 nexp 是 (+ 1 3)

现在递归

是的。

(cdr nexp) 是什么 其中 nexp 是 (+ 1 3)

(1 3)

(1 3) 现在i是我们算术表达式的表达了

不,我们违反了第七戒。(1 3)子部分不是一个算术表达式的表达。我们对一个list表做递归。但是不是所有的list都是算术表达式的表达。我们必须是对子表达式做递归。

怎样得到算术表达式的第一个子表达式

取cdr再去car。就是第二个list成员。

(cdr (cdr nexp)) 是一个算术表达式吗

不是,取cdr再取cdr就是(3)了,(3)不是算术表达式

再一次,我们之前把(+ 1 3)考虑的是表而不是算术表达式的表达。

取cdr取cdr再去car就得到了第二个子表达式,就是第三个list成员。

nexp取cdr再取nexp是什么

算术表达式的表达的第一个子表达式

我们来为算术表达式写一个函数1st-sub-exp

(define 1st-sub-exp
  (lambda (aexp)
    (cond
      (else (car (cdr aexp))))))

为什么else

因为第一个查询也是最后一个查询

我们可以把(cond ...)去掉吗,既然不需要分支查询

当然,第四章的rember一行版本的就是这样子的

(define 1st-sub-exp
  (lambda (aexp)
    (car (cdr aexp))))

为算术表达式写函数 2nd-sub-exp

(define 2nd-sub-exp
  (lambda (aexp)
    (car (cdr (cdr aexp)))))

最后我们把(car nexp)替换为(operator nexp)
(define  operator
  (lambda (aexp)
    (car aexp)))

现在再一次重写函数value

(define (atom? x)
  (and (not (null? x))
       (not (pair? x))))

(define operator
  (lambda (aexp)
    (car aexp)))

(define 1st-sub-exp
  (lambda (aexp)
    (car (cdr aexp))))

(define 2nd-sub-exp
  (lambda (aexp)
    (car (cdr (cdr aexp)))))

(define value
  (lambda (nexp)
    (cond
      ((atom? nexp) nexp)
      ((eq? (operator nexp) (quote +)) (+ (1st-sub-exp nexp) (2nd-sub-exp nexp)))
      ((eq? (operator nexp) (quote ×)) ('× (1st-sub-exp nexp) (2nd-sub-exp nexp)))
      (else ('^ (1st-sub-exp nexp) (2nd-sub-exp nexp))))))

我们可以对这一章的算术表达式的表达使用value函数吗

可以,通用改为使用 1st-sub-exp和 operator

试试看
(define 1st-sub-exp
  (lambda (aexp)
    (car (cdr aexp))))

(define operator
  (lambda (aexp)
    (car aexp)))

很简单不是吗

是的,因为我们用辅助函数来隐藏表达。

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
第八戒

使用辅助函数来抽象表达
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

我们之前见到过表达没

是的,只不过我们没告诉你

我们用过哪写表达

真值!数!

数是表达?

是的。比如说4是概念“4”。我们使用符号因为我们习惯阿拉伯数字表达。

我们还可以用什么表示呢

(() () () ())也可以表示。(((())))如何?(I V)怎么样?

还记得我们有多少个对数使用的元函数吗

四个:numbers? zero? add1和sub1

让我们再试试数的其它表示,零怎么表示

我们选择()

1 怎么表示
(())

2 怎么表示

(() ())

知道了?那3呢

(() () ())

写一个函数来测试是否是zero零

(define sero?
  (lambda (n)
    (null? n)))

写一个像add1函数的函数

(define edd1
  (lambda (n)
    (cons (quote ()) n)))

那sub1呢

(define zub1
  (lambda (n)
    (cdr n)))

这样对吗

让我们瞧瞧看

当n是()时(zub1 n)是多少

没有答案,但是没有关系。——回忆cdr的规则。

使用表达重写+

(define +
  (lambda (n m)
    (cond
      ((sero? m) n)
      (else (edd1 (+ n (zub1 m)))))))

+变了吗

Yes and no.它变化了,但是只是一点点。

回忆lat?

很简单:
(define lat?
  (lambda (l)
    (cond
      ((null?) #t)
      ((atom? (car l)) (lat? (cdr l)))
      (else #f))))
问这个干吗

还记得当ls是(1 2 3)时,(lat? ls)是什么吗

真,当然了。

对于我们的新数,(1 2 3)是什么

((()) (() ()) (() () ()))

那当ls是((()) (() ()) (() () ()))时,(lat? ls)是什么

这样有什么坏的地方吗

你必须得提防shadows了。


This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 2.5 China Mainland License.

posted @ 2019-01-21 10:21 史D芬周 阅读(...) 评论(...) 编辑 收藏

the little schemer 笔记(6)相关推荐

  1. the little schemer 笔记(5)

    the little schemer 笔记(5) 第五章 "Oh My Gawd":It's Full of Stars (rember* a l)是什么,其中a是cup,l是(( ...

  2. the little schemer 笔记(3)

    第三章 cons the magnificent (rember a lat)是什么,其中a是mint,lat是(lamb chops and mint jelly) (lamb chops and ...

  3. the little schemer 笔记(7)

    第七章 Friends and Relations 这是一个set集合吗 (apple peaches apple plum) 不是,apple出现了不止一次 (set? lat) 是真还是假,其中l ...

  4. The Little Shemer笔记

    ;;预备函数 (define (atom? x)(and (not (pair? x))(not (null? x)))) (define (sub1 x)(- x 1)) (define (add1 ...

  5. 【读书笔记】知易行难,多实践

    前言: 其实,我不喜欢看书,只是喜欢找答案,想通过专业的解答来解决我生活的困惑.所以,我听了很多书,也看了很多书,但看完书,没有很多的实践,导致我并不很深入在很多时候. 分享读书笔记: <高效1 ...

  6. 【运维学习笔记】生命不息,搞事开始。。。

    001生命不息,搞事不止!!! 这段时间和hexesdesu搞了很多事情! 之前是机械硬盘和固态硬盘的测速,我就在那默默的看着他一个硬盘一个机械测来测去. 坐在他后面,每天都能看到这位萌萌的小男孩,各 ...

  7. SSAN 关系抽取 论文笔记

    20210621 https://zhuanlan.zhihu.com/p/353183322 [KG笔记]八.文档级(Document Level)关系抽取任务 共指id嵌入一样 但是实体嵌入的时候 ...

  8. pandas以前笔记

    # -*- coding: utf-8 -*- """ Created on Sat Jul 21 20:06:20 2018@author: heimi "& ...

  9. PyTorch 学习笔记(六):PyTorch hook 和关于 PyTorch backward 过程的理解 call

    您的位置 首页 PyTorch 学习笔记系列 PyTorch 学习笔记(六):PyTorch hook 和关于 PyTorch backward 过程的理解 发布: 2017年8月4日 7,195阅读 ...

  10. 容器云原生DevOps学习笔记——第三期:从零搭建CI/CD系统标准化交付流程

    暑期实习期间,所在的技术中台-效能研发团队规划设计并结合公司开源协同实现符合DevOps理念的研发工具平台,实现研发过程自动化.标准化: 实习期间对DevOps的理解一直懵懵懂懂,最近观看了阿里专家带 ...

最新文章

  1. value_counts()
  2. 心得---字节流、文件操作、对象序列化
  3. 博通的“交钥匙”策略
  4. 设置手机项目首选参数
  5. 176条DevOps人员常用的Linux命令速查表
  6. typora的安装和配置
  7. error LNK2001的一些原因
  8. 如何缩小jpg图片大小?jpg格式怎么压缩?
  9. mvvm框架 android,Android MVVM 框架 MVVMFramework
  10. 惋惜!杭州互联网公司22岁女孩猝死!某大厂家属怒喷996的工作方式...
  11. java split竖线_java对竖线|进行分割(split)操作
  12. 打造云原生大型分布式监控系统
  13. osx snow leopard下用homebrew 安装php5.3 + php-fpm
  14. Teredo tunneling pseudo-interface前面有个黄色感叹号
  15. vue+echarts的组件封装
  16. Python中的os.chdir()函数:改变当前工作目录
  17. 云服务器 ghost系统,在Ubuntu 18.04操作系统上安装Ghost CMS的步骤
  18. R语言实战笔记--第十二章 重抽样(置换检验)与自助法
  19. 通达信指标公式常用绘图函数(4)——颜色、线形粗细、线型等修饰函数
  20. linux 动态图片制作,Ubuntu 17.10下使用kazam制作gif动态图片

热门文章

  1. 5G相比LTE 大的差异
  2. Dialog dismiss 和 cancel的区别
  3. YApi 高级mock脚本 1.8.3版本后,mockJson不能正确返回问题
  4. 一群参与境内外赌博网站的开发的程序员被抓,网友:切勿面向监狱编程。。。...
  5. java导出繁体字word,word繁体字转换
  6. 易企CMS采集助力网页快速收录
  7. Unity-URP-基于模板的延迟渲染
  8. 英读廊——一个人的旅行:原汁原味希腊克里特游记
  9. android xcl charts,我写的Android图表库XCL-Charts,整理好现在开源了!!!
  10. package.json scripts 脚本使用指南