闲来无事,鼓起勇气翻开《SICP》。准备好好地夯实自己的基础,同时理解函数式编程,留此系列博客,以备忘。
一、mit-scheme在ubuntu上的安装
命令行安装,还是挺简单的。
sudo apt-get install mit-scheme
命令行打开。
mit-scheme
二、scheme语法入门,主要是参考了《Yet Another Scheme Tutorial》这本书
这本书初学者入门很合适,而且附带有习题及习题答案。
中文翻译版地址http://deathking.github.io/yast-cn/contents/
目录如下
- 中文版序
- 安装MIT-Scheme
- 将Scheme用作计算器
- 生成表
- 定义函数
- 分支
- 局部变量
- 重复
- 高阶函数
- 输入/输出
- 赋值
- 字符与字符串
- 符号
- 关联表和哈希表
- 向量和结构体
- 定义语法
- 继续
- 惰性求值
- 非确定性求值
教程学习摘要:
1、第5章练习2,总感觉题目中的自由落体公式没有讲清楚,意思含混,公式可能是错的。当然,对语法学习没有影响。
2、第8章,练习一第3 题。
3、一个分别接受一个表ls和一个对象x的函数,该函数返回从ls中删除x后得到的表。
答案中lambda的使用让我有点迷惑,不知道这里的lambda匿名函数有什么特别之处。代码有三个版本,其实递归的思路都一样,对cons magic的使用都差不多。如下:
;自己的版本
(define (remove x ls)
(if (null? ls)
'()
(if (eqv? (car ls) x)
(remove x (cdr ls))
(cons (car ls) (remove x (cdr ls)))))))
; 《yast》版本
(define (remove x ls)
(if (null? ls)
'()
(let ((h (car ls)))
(
(if (eqv? x h)
(lambda (y) y)
(lambda (y) (cons h y))
)
(remove x (cdr ls))))))
; 《the little scheme》版本
(define remove
(lambda (a lat)
(cond
((null? lat) (quote ()))
(else (cond
((eqv? (car lat) a) (cdr lat))
(else (cons (car lat)
(remove a (cdr lat)))))))))
“不知怎么在markdown调整代码格式。心伤啊。”
3、第8章,练习1第4题:一个分别接受一个表ls和一个对象x的函数,该函数返回x在ls中首次出现的位置。索引从0开始。如果x不在ls中,函数返回#f。
(define (findplace x ls i)
(if (null? ls)
#f
(if (eqv? x (car ls))
i
(findplace x (cdr ls) (1+ i)))
))
代码通过。但是疑惑的量,函数 1+ 好像并不能改变变量自身的值啊,只是返回值增1,并不是自增1啊?理解有误?嗯,应该是我理解错了,《SICP》应该会讲这个函数。
另外,Scheme将尾递归转化为循环,Scheme就无需提供循环的语法来实现重复。嗯,感觉很牛逼的样子,觉着scheme是那样的清纯。
做完后面的习题,发现确实牛啊。编码的确是思想第一,代码第二,在这里深深体会到了。
4、第8章 命名 let 来表达循环仍然是在尾递归的基础上实现的,思想一样。let 、 letrec 、 do 这几个形式看着好不习惯啊。
5、第9章高阶函数粗略地看了一下,要深究的话…..嗯,还是不要了。那两个曲线绘制的东东就先略过吧。
6、“在Scheme中,你可以编写返回过程的过程,因此你可以编写一个创建银行账户的函数。这个例子喻示着使用函数式程序设计语言可以很容易实现面向对象程序设计语言。实际上,只需要在这个基础上再加一点东西就可以实现一门面向对象程序设计语言了。”——似懂非懂啊。
7、第11章 队列的实现要多看一看,对数据结构的实现很重要的东西。
8、字符串是严格按照双引号来表示的,单引号绝对不行! 字符串索引函数也是从 0 开始的!
9、scheme的 let loop循环结构绝对重要啊。要多练习。第12章的习题很好,两种思路,其一利用scheme的cons结构来循环,其二利用计数循环,都很重要。
10、第14章这个生成密码程序没看,好头大啊。
11、最后3章看的云里雾里的,等用到时再回头来看吧。
粗略温习完scheme语法,开始啃书吧。
对了,在温习过程中发现 了一个博客,讲解scheme语法的,作为快速入门也不错。地址:http://www.ibm.com/developerworks/cn/linux/l-schm/index1.html