代码改变世界

《计算机程序的构造和解析》第一章复习笔记

2011-11-12 16:07  撞破南墙  阅读(604)  评论(0编辑  收藏  举报
前言 
一个好的编程语言不只是指挥电脑去实现任务。更是作为一个框架,通过它来组织我们思考实现任务计算的过程。
这样,当我们描述一个语言的时候,我们应该额外去关注如何组织简单的思想去表达复杂的想法。每个强大的语言都有3个机制去实现它。
1 基本表达式(primitive expressions)。他表达了整个语言最简单的个体,也就是最基本的组成部分。
2 组合的方法(means of combination)。将简单单元结合成复杂的结构的方法。
3 抽象的方法(abstraction),作为单元来命名和操作混合元素(此处的混合元素包括混合的数据结构和方法)。
@在此处,用系统的观点看,1个是组份,第二个是关系,第三个是方法/动作。
以C语言来看,其
基本的表达式是由基本语法所能够写出来的基本表达式语句和基本的数据结构。
组合的方法是使用结构体(思想)的方法来组装最简单的数据结构。
抽象的方法是函数。
在编程中,我们处理两种基本类型:过程和数据。(稍后我们会看到,他们并没有如此清晰的界限)。不严谨的说,数据是这样的东西,我们将操作他,而过程呢,被描述为规则和操作数据。如此,任何强大的编程语言应该诶描述为原始数据和原始过程,并且应该有方法去连接和抽象
过程和数据。
这一章,我们将只处理简单的数字数据,以便我们集中精力在构造过程。后面的章节,我们将看到一样的规则去构造过程来操作数据。

 

1.1.1表达式

lisp使用前缀表达。可以接受多个参数。参数也可以是表达式。可以嵌套多层。
(* 25 4 12)
(+ (* 3 5) (- 10 6))

 

1.1.2命名和环境

使用define 作为 起别名/定义变量 的关键词。
(define size 2)

 

1.1.4  复合过程

过程定义的一般形式:
(define (<name> <formal parameters>))

 

1.1.5 过程应用的代换模型

为了求值1个组告式(其运算符是一个复合过程的名字) ,解释器的工作方式将完全按照1.1 .3节中所描述的那样, 用与以运算符名为基本过程的组合式一样的计算过程。也就是说,
解释器将对组合式的各个元素求值,而后将得到的那个过程(也就是该组合式里运算符的值)
应用于那些实际参数(即组合式里那些运算对象的值).
但是简单的代换模型,后面将给出更深入的讨论和实现。
正则序求值:完全屉开而后归的 的求值模型
应用序求值:先求值参数而后应用。(lisp采用的方法:避免对于表达式重复求职)

 

1.1.6条件表达式和谓词

 
写法1
(define (abs x)
  (cond ((> x 0) x)
        ((= x 0) 0)
        ((< x 0) (- x))))
如果无法匹配则返回未定义
写法2
(define (abs x)
  (cond ((< x 0) (- x))
        (else x)))
写法3
(define (abs x)
  (if (< x 0) (- x)
      x))
三个 逻辑 符合谓词
(and <e1> ... <en>) 
(or <e1> ... <en>)
(not <e1> ... <en>)

 

1.3 用高阶函数做抽象

 

1.3.1 过程作为参数

将函数名作为函数的参数传递,类似C中的函数指针和C#中的委托。
lisp里不需要检查函数的参数列表、类型。
此处的sum term next 即 为过程参数
(define (sum term a next b)
(if(>ab)
o
(+ (term a)
(sum term (next a) next b))))

 

1.3.2 用lambda构造过程

类似c#的lambda,直接构造一个匿名过程,通常作为参数供别人使用。
{lambda (x) (+ x 4))

 

1.3.3 过程作为返回值

过程在lisp里如数据一样,可以作为参数传递。
(defineine (average-damp f)
(lambda (x) (average x (f x))))