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.
the little schemer 笔记(6)的更多相关文章
- the little schemer 笔记(0)
the little schemer 笔记 Z.X.L 2012年08月13日 五项规则 car的规则car只对非空列表有定义. cdr的规则cdr只对非空列表有定义.任何非空列表的cdr是另外一个列 ...
- the little schemer 笔记(10)
第十章 What Is the Value of All of This? entry条目 是由list表组成的 pair 对,pair 对的第一个list表是集合 set.另外,两个list表的长 ...
- the little schemer 笔记(3)
第三章 cons the magnificent (rember a lat)是什么,其中a是mint,lat是(lamb chops and mint jelly) (lamb chops and ...
- the little schemer 笔记(10.1)
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 2.5 China Mainla ...
- the little schemer 笔记(9)
第九章 ...and Again, and Again, and, Again, ... 你想来点鱼子酱吗? 那就去找它吧. (looking a lat)是什么,其中a是 caviar, lat是( ...
- the little schemer 笔记(8)
第八章 lambda the ultimate 还记得我们第五章末的rember和insertL吗 我们用equal?替换了eq? 你能用你eq?或者equal?写一个函数rember-f吗 还不能, ...
- the little schemer 笔记(5)
第五章 “Oh My Gawd”:It's Full of Stars (rember* a l)是什么,其中a是cup,l是((coffee) cup ((tea) cup) rember*发音为r ...
- the little schemer 笔记(7)
第七章 Friends and Relations 这是一个set集合吗 (apple peaches apple plum) 不是,apple出现了不止一次 (set? lat) 是真还是假,其中l ...
- the little schemer 笔记(4)
第四章 numbers games 14 是原子吗 是的,数都是原子 (atom? n) 是真还是假,其中n是14 真,14 是原子 -3是数吗 是的,不过我们暂不考虑负数 3.14159是数吗 是的 ...
随机推荐
- DBExecutor android 数据库框架
https://github.com/eltld/DBExecutor android 数据库框架,sqlite database
- 项目Beta冲刺(团队4/7)
项目Beta冲刺(团队4/7) 团队名称: 云打印 作业要求: 项目Beta冲刺(团队) 作业目标: 完成项目Beta版本 团队队员 队员学号 队员姓名 个人博客地址 备注 221600412 陈宇 ...
- vc6.0的一些快捷键
1.检测程序中的括号是否匹配 把光标移动到需要检测的括号(如大括号{}.方括号[].圆括号()和尖括号<>)前面,键入快捷键“Ctrl+]”.如果括号匹配正确,光标就跳到匹配的括号处 ...
- DRF 之 路由组件
组件路由的步骤 1.先要导入DefaultRouter from rest_framework.routers import DefaultRouter 2.实例化DeaultRouter对象 rou ...
- Deep Learning 36:python中的一些函数
1.map(function, sequence[, sequence, ...])函数:返回一个list作用:map的作用是以参数序列中的每一个元素调用function函数,返回包含每次functi ...
- TFS Server 2017 自动化部署步骤
1 第一步,在服务器上安装TFS 2 第二步,安装完TFS后需要配置你的项目,选择管理代码的方式,这里我们可以选择传统的TFS 也可以选择GIT 方式,此处我选择的GIT 方式 3 第三步,设置代理. ...
- IO、FileInputStream、(二十)
1.IO流概述及其分类 * 1.概念(什么是IO?) * IO流用来处理设备之间的数据传输 * Java对数据的操作是通过流的方式 * Java用于操作流的类都在IO包中 * 流按流向分为两种:输入流 ...
- 安装程序工具 (Installutil.exe)
网址:https://msdn.microsoft.com/zh-cn/library/50614e95(VS.80).aspx 安装程序工具 (Installutil.exe) .NET Fram ...
- UVA-10827(前缀和降维)
题意: 给一个n*n的正方形,第一行和最后一行粘在一块,第一列和最后一列粘在一块,求这个环面上的最大的子矩形; 思路: 直接暴力是O(n^6)的复杂度,可以把前缀和求出来,这样就可以只用枚举四条边界就 ...
- 「LuoguP2434」 [SDOI2005]区间(贪心
Description 现给定n个闭区间[ai, bi],1<=i<=n.这些区间的并可以表示为一些不相交的闭区间的并.你的任务就是在这些表示方式中找出包含最少区间的方案.你的输出应该按照 ...