diff --git a/sicp/3/2.md b/sicp/3/2.md index 4be07b6..8d6d7aa 100644 --- a/sicp/3/2.md +++ b/sicp/3/2.md @@ -20,12 +20,14 @@ Scheme 程序主要是由各种表达式构成的,这些表达式可以是函 ```scheme (quotient 10 2) +5 ``` Scheme 的语法一直采用前缀形式。也就是说,操作符像 `+` 和 `*` 都放在前面。函数调用可以互相嵌套,并且可能会写在多行上: ```scheme (+ (* 3 5) (- 10 6)) +19 ``` ```scheme @@ -34,6 +36,7 @@ Scheme 的语法一直采用前缀形式。也就是说,操作符像 `+` 和 ` (+ 3 5))) (+ (- 10 7) 6)) +57 ``` 在 Scheme 中,表达式可以是基础类型,如数字,或是复合类型,如函数调用。数字字面量是基础类型,而函数调用则是可以包含任意子表达式一种复合形式。当求值一个函数调用时,Scheme 的处理方式和 Python 相似:首先对操作符和操作数进行求值,然后用操作符的结果(即函数)去处理操作数的结果(即参数)。 @@ -50,6 +53,7 @@ Scheme 的语法一直采用前缀形式。也就是说,操作符像 `+` 和 ` ```scheme (>= 2 1) +true ``` Scheme 中的布尔值有 `#t` 或者 `true` 代表真和 `#f` 或 `false` 代表假。你可以使用一些特定的布尔操作来组合它们,这些操作的执行逻辑和 Python 里的很相似。 @@ -65,6 +69,7 @@ Scheme 中的布尔值有 `#t` 或者 `true` 代表真和 `#f` 或 `false` 代 ```scheme (define pi 3.14) (* pi 2) +6.28 ``` 你可以用 `define` 的另一个版本来定义新的函数(在 Scheme 中,我们称之为“过程”)。例如,如果我们想定义一个求平方的函数,可以这样写: @@ -85,10 +90,13 @@ Scheme 中的布尔值有 `#t` 或者 `true` 代表真和 `#f` 或 `false` 代 ```scheme (square 21) +441 (square (+ 2 5)) +49 (square (square 3)) +81 ``` 用户自定义的函数可以接受多个参数,并且还可以包含特殊形式: @@ -98,6 +106,7 @@ Scheme 中的布尔值有 `#t` 或者 `true` 代表真和 `#f` 或 `false` 代 (/ (+ x y) 2)) (average 1 3) +2 ``` ```scheme @@ -105,6 +114,8 @@ Scheme 中的布尔值有 `#t` 或者 `true` 代表真和 `#f` 或 `false` 代 (if (< x 0) (- x) x)) +(abs -3) +3 ``` Scheme 支持与 Python 相同的词法作用域规则,允许进行局部定义。下面,我们使用嵌套定义和递归定义了一个用于计算平方根的迭代过程: @@ -121,6 +132,7 @@ Scheme 支持与 Python 相同的词法作用域规则,允许进行局部定 (sqrt-iter (improve guess)))) (sqrt-iter 1.0)) (sqrt 9) +3.00009155413138 ``` 匿名函数是通过 `lambda` 特殊形式创建的。`Lambda` 用于创建过程,与 `define` 相似,但不需要为过程指定名称: @@ -140,6 +152,7 @@ Scheme 支持与 Python 相同的词法作用域规则,允许进行局部定 ```scheme ((lambda (x y z) (+ x y (square z))) 1 2 3) +12 ``` ## 3.2.3 复合类型 @@ -150,10 +163,13 @@ Scheme 支持与 Python 相同的词法作用域规则,允许进行局部定 (define x (cons 1 2)) x +(1 2) (car x) +(1) (cdr x) +(2) ``` Scheme 语言中也内置了递归列表,它们使用 `pair` 来构建。特殊的值 `nil` 或 `'()` 表示空列表。递归列表的值是通过将其元素放在括号内,用空格分隔开来表示的: @@ -164,19 +180,25 @@ Scheme 语言中也内置了递归列表,它们使用 `pair` 来构建。特 (cons 3 (cons 4 nil)))) +(1 2 3 4) (list 1 2 3 4) (define one-through-four (list 1 2 3 4)) (car one-through-four) +1 (cdr one-through-four) +(2 3 4) (car (cdr one-through-four)) +(2) (cons 10 one-through-four) +(10 1 2 3 4) (cons 5 one-through-four) +(5 1 2 3 4) ``` 要确定一个列表是否为空,可以使用内置的 `null?` 谓词。借助它,我们可以定义用于计算长度和选择元素的标准序列操作: @@ -193,8 +215,9 @@ Scheme 语言中也内置了递归列表,它们使用 `pair` 来构建。特 (define squares (list 1 4 9 16 25)) (length squares) - +5 (getitem squares 3) +16 ``` ## 3.2.4 符号数据 @@ -208,24 +231,27 @@ Scheme 语言中也内置了递归列表,它们使用 `pair` 来构建。特 (define b 2) (list a b) - +(1 2) (list 'a 'b) - +(a b) (list 'a b) +(a 2) ``` 在 Scheme 中,任何不被求值的表达式都被称为被引用。这种引用的概念源自一个经典的哲学区分,即一种事物(比如一只狗)会四处奔跑和吠叫,而“狗”这个词是一种语言构造,用来指代这种事物。当我们在引号中使用“狗”时,我们并不是指代某只特定的狗,而是指代一个词语。在语言中,引号允许我们讨论语言本身,而在 Scheme 中也是如此: ```scheme (list 'define 'list) +(define list) ``` 引用还使我们能够输入复合对象,使用传统的打印表示方式来表示列表: ```scheme (car '(a b c)) - +(a) (cdr '(a b c)) +(b c) ``` 完整的 Scheme 语言包括更多功能,如变异操作(mutation operations)、向量(vectors)和映射(maps)。然而,到目前为止,我们介绍的这个子集已经提供了一个强大的函数式编程语言,可以实现我们在本文中讨论过的许多概念。