SICP学习记录00
1.1 程序设计的基本元素
前文
搭建Scheme环境。
我们编写lisp程序需要相对应的IDE,地址在这
相关IDE 。
下载安装完成后点击 打开IDE。
界面大概是这样子的。
最后,通过上面的提示,即可完成。
正文
define关键字
在程序设计语言中有一个必不可少的方面,就是它需要提供一种通过名字去使用计算对象的方式。这名字标识就是变量,它的值就是它所对应的那个对象。
在Scheme中,给对象取名字是通过define
完成,例如
(define size 2)
就是把2这个对象取名字为size
。
可以看到,对于这个解释器来说,他必须知道size
和2这个对象是一一对应的,这意味着解释器必须维护某种存储能力,以便保存他们的对应关系。
正则序和应用序
正则序:先不求运算对象的值,直到实际需要他们的值的时候在求值。
应用序:先求参数实际值,然后再展开应用。
。。。。。。。。。。。。。。。。。。。。。。。
练习
1.3
(define (minF minA minB) (if(< minA minB) minA minB ) ) (define (sum a b c) (+ a b c)) (define (sum_of_max a b c) (- (sum a b c) (minF (minF a b) c)) )
1.4
如果b>0,则a+b,否则a-b。
1.5
看不到结果,会死循环,因为应用序会一直对(p)求值,求出来又是(p)。但是如果是正则序的话就会得到0,因为if语句还没到给(p)求值就已经完成了。
1.6
无限递归,无法终止递归。因为无论predicate
是否为真,他都会展开执行else_clause
。对于应用序,他就会先求出then_clause
的值,比如我们sqrt_iter 1.0 16
,先求出sqrt_iter guess x
中guess
的值为1.0,再求出x
的值为16,然后进入sqrt_iter
内部,碰到第一个语句
(new_if (good_enough? guess x) guess (square_iter (improve guess x) x) )
会先求出good_enough? 1.0 16
的值为false
然后再求出guess
的值为1.0,然后再求出sqrt_iter (improve guess x) x
的值,最后带着这些求出来的值,进入new_if
内部中去,但是,因为我们求(square_iter (improve guess x) x)
又会碰到同样的事,所以我们始终无法求出这个的值,最后就会陷入死循环挂掉。(对于正则序也一样,这个程序将会一直展开(square_iter (improve guess x) x)
这个过程)
也就是说,如果没有这个特殊的if
,我们将会在处理它的参数时候无限递归而死机。
1.7
对于小于差值0.001的X的值,例如0.000001时,正确值是0.001,而我们方法则是0.031260655525445276,这是为什么呢,因为我们猜测的数字是从1.0逐渐变小。当减小到0.031260655525445276的时候,就会因为0.031260655525445276的平方本身就小于0.001而导致good_enough
返回真,然而这是不对的。
对于很大的数。由于机器的表示方法,我们无法表示更加确切的猜测值,导致当guess值已经是能表示的最精确的值时,good_enough中返回的还是假。(即guess的平方减x的绝对值已经达到最小但还是大于0.001)
1.11
递归
(define (f n) (if(< n 3) n (+ (f (- n 1)) (* 2 (f (- n 2))) (* 3 (f (- n 3))))) ) (f 9)
迭代
(define (f n) (define(f_iter n_1 n_2 n_3 a) (if(< a 3) (cond ((= a 0) n_3) ((= a 1) n_2) (else n_1)) (f_iter (+ n_1 (* 2 n_2) (* 3 n_3)) n_1 n_2 (- a 1)))) (f_iter 2 1 0 n) )
1.12
(define (f y x) (if (or (= x 1) (= x y)) 1 (+(f (- y 1) (- x 1)) (f (- y 1) x ))))
1.31
(define (product term a next b) (if (> a b) 1 (* (term a) (product term (next a) next b)))) (define (factorial a) (product (lambda(x)x) 1 (lambda(x)(+ 1 x)) a))
#lang racket (define (product term a next b) (if (> a b) 1 (* (term a) (product term (next a) next b)))) (define f (product (lambda(x)(* (- 1 (/ 1 x)) (+ 1 (/ 1 x)))) 3 (lambda(x)(+ 2 x)) 111))
1.34
从(f f)
到(f 2)
到(2 2)
,但是会因为(2 2)
中的第一个2不是一个过程,然后失败。