3.2.scheme语言介绍

\(3.2\;scheme\)语言介绍

1.基本表达式

  \(a.\)数字

1
2
3
4
scm> 1234    ; integer
1234
scm> 123.4 ; real number
123.4

  \(b.\)标志\(symbol\)

  标志是\(scheme\)语言特有的类型。在\(scheme\)语言中,标志本身可以作为一个值,而在\(python\)中的“标志”只是作为表达式的名称存在。

1
2
3
4
5
6
scm> quotient      ; A name bound to a built-in procedure
#[quotient]
scm> 'quotient ; An expression that evaluates to a symbol
quotient
scm> 'hello-world!
hello-world!

  \(c.\)布尔值

  在\(scheme\)语言中,除了#f外的所有值都是\(true\),这和\(python\)的零值为\(false\)不同。\(scheme\)#t表示\(true\),用#f表示\(false\)

1
2
3
4
scm> #t
#t
scm> #f
#f

2.调用表达式

  与\(Python\)类似,\(Scheme\)调用表达式中的操作符位于所有操作数之前。与 \(Python\)不同,操作符包含在括号内,且操作数用空格而不是逗号分隔,计算的具体流程如下:

  1. 计算操作符,决定运算规则。
  2. 从左到右考虑操作数。
  3. 将运算规则作用于操作数上。

  这也是\(scheme\)语句一般地执行方法。但之后讲解的规则与这个不同,被称作“特殊规则”。

1
2
3
4
5
6
7
8
scm> (+ 1 2)
3
scm> (- 10 (/ 6 2))
7
scm> (modulo 35 4)
3
scm> (even? (quotient 45 2))
#t

3.控制结构

  \(a.\)if语句

  \(scheme\)中的if语句结构如下:

1
(if <predicate> <if-true> [if-false])

  该结构的<if-true>部分与[if-false]部分只能接受一个表达式,与\(python\)不同。该结构的一个运行实例如下:

  \(scheme\)中没有elif语句,实现该功能只能通过if的嵌套:

  \(b.\)cond表达式

  cond表达式类似switch语句,其结构如下:

1
2
3
4
5
6
(cond
(<p1> <e1>)
(<p2> <e2>)
...
(<pn> <en>)
[(else <else-expression>)])
  每个从句中的第一个表达式就相当于<predicate>,当<predicate>为真,就执行后面的语句并终止程序。该表达式的一个具体实例如下:

4.数据结构

  \(a.\)链表

  \(scheme\)中的链表是通过一系列\(pair\)构建的,它通过\(constructor\)cons创建。

  链表的\(rest\)元素,即cdr操作,是别的链表或nil,空链表:

1
2
scm> (cons 1 (cons 2 (cons 3 nil)))
(1 2 3)

  可以通过carcdr语句获取链表中的元素值:

1
2
3
4
5
6
7
8
9
10
scm> (define a (cons 1 (cons 2 (cons 3 nil))))  ; Assign the list to the name a
a
scm> a
(1 2 3)
scm> (car a)
1
scm> (cdr a)
(2 3)
scm> (car (cdr (cdr a)))
3

  如果在\(pair\)中不传入另一个\(pair\)nil作为cons的第二个参数,程序会报错:

1
2
scm> (cons 1 2)
Error

  \(b.\)列表

  创建列表的方法有很多种,可以直接用list创建:

1
2
3
4
5
6
scm> (list 1 2 3)
(1 2 3)
scm> (list 1 (list 2 3) 4)
(1 (2 3) 4)
scm> (list (cons 1 (cons 2 nil)) 3 4)
((1 2) 3 4)

  注意cons函数只能接受两个参数,如果要在一个链表里面插入多个元素,可以采用多个cons嵌套的方法:

1
2
3
4
5
6
7
8
9
(define (interleave first second)
'YOUR-CODE-HERE
(cond
((null? first) second)
((null? second) first)
(else (cons (car first)
(cons (car second)
(interleave (cdr first) (cdr second))))))
)

  还可以通过单引号语句创建,语句中的'不会被读入:

1
2
3
4
5
6
scm> '(1 2 3)
(1 2 3)
scm> '(cons 1 2) ; Argument to quote is not evaluated
(cons 1 2)
scm> '(1 (2 3 4))
(1 (2 3 4))

  列表有与\(python\)类似的操作:

1
2
3
4
5
6
scm> (null? nil)                ; Checks if a value is the empty list
True
scm> (append '(1 2 3) '(4 5 6)) ; Concatenates two lists
(1 2 3 4 5 6)
scm> (length '(1 2 3 4 5)) ; Returns the number of elements in a list
5

5.定义语句

  定义语句用于定义变量与函数。定义语句的结构如下:

1
(define <name> <expression>)
  该语句通过以下流程实现: 1. 计算<expression>的值 2. 将值与name绑定 3. 返回name

  只有在调用define<body>才会被执行。

6.\(lambdas\)

  \(scheme\)中的\(lambda\)语句如下:

1
(lambda (<param1> <param2> ...) <body>)

  \(lambda\)的具体实例如下:

1
2
3
scm> (lambda (x y) (+ x y))        ; Returns a lambda function, but doesn't assign it to a name
(lambda (x y) (+ x y))
scm> ((lambda (x y) (+ x y)) 3 4) ; Create and call a lambda function in one line