The Scheme Programming Language 读书笔记,chapter 4.
Chapter 4. Procedures and Variable Bindings
执行诀和变量绑定是Scheme程序的两大基石。
Section 4.1. Variable References
变量绑定通常由define,lambda,let等等语法形式创建的。一个标识符被当作表达式的时候,如果相关的变量绑定存在,那么这个标识符则被当作一个变量。
如果在library形式或者顶层程序引用了某个标识符,并且相应的变量绑定不存在,那么这是一个语法上的错误。它们必须指定一个变量,关键字,记录名,或者其他实体。下面的代码在语法上是错误的:
(define q (g 3))
(define g
(lambda (x)
(+ x x))
但是如果实际的引用出现在定义之后,则是可以的。
(define f
(lambda (x)
(g x)))
(define g
(lambda (x)
(+ x x)))
Section 4.2. Lambda
lambda语法形式用来执行诀。任何创建执行诀或者创建局部变量绑定的操作最终都是通过lambda或者case-lambda定义的。
The body may begin with a sequence of definitions, 这句话不太了解。
当执行诀创建的时候,除了形参之外,之内那些自由性的变量绑定会被留存在执行诀内部。但执行诀施用的时候,形参会绑定到实参,留存的变量绑定会被复原,内容被执行。
关于形参绑定的三种形式,前面章节已经介绍过了。当执行的时候,执行诀包含的表达式会被逐条执行,并返回最后一条表达式的结果。
Section 4.3. Case-Lambda
case-lambda创建的执行诀可以接受可选参数。其形式是:(case-lambda clause ...)
。也就是可以接受多个clause,每个clause的形式是:[formals body1 body2 ...]
。
当case-lambda被调用的是,会按顺序查看各个clause,找到第一个参数个书匹配的clause执行。如果没有能够匹配成功,那么会报告&assertion类型的异常。
下面是一个例子:
(define make-list
(case-lambda
[(n) (make-list n #f)]
[(n x)
(do ([n n (- n 1)] [ls '() (cons x ls)])
((zero? n) ls))]))
Section 4.4. Local Binding
let语法形式(let ((var expr) ...) body1 body2 ...)
用来创建局部变量绑定。
典型的let的语法定义:
(define-syntax let
(syntax-rules ()
[(_ ((x e) ...) b1 b2 ...)
((lambda (x ...) b1 b2 ...) e ...)]))
此外由let*,跟let功能类似,不过其变量绑定的时候是按左到右求值。
let*可以由嵌套的let定义:
(define-syntax let*
(syntax-rules ()
[(_ () e1 e2 ...)
(let () e1 e2 ...)]
[(_ ((x1 v1) (x2 v2) ...) e1 e2 ...)
(let ((x1 v1))
(let* ((x2 v2) ...) e1 e2 ...))]))
letrec,形式为(letrec ((var expr) ...) body1 body2 ...)
,和前面的let和let*类似,不过变量绑定的时候允许互相调用:
(letrec ([sum (lambda (x)
(if (zero? x)
0
(+ x (sum (- x 1)))))])
对于letrec的另一个限制是其expr不能返回两次。
letrec适用在((var expr) ...)
的expr…有循环引用的情况下。在需要从左到右对expr…求值的时候,使用letrec*。
letrec的语法形式的一种定义:
(let ((var #f) ...)
(let ((temp expr) ...)
(set! var temp) ...
(let () body1 body2 ...)))
letrec*的语法形式的一种定义:
(let ((var #f) ...)
(set! var expr) ...
(let () body1 body2 ...))
Section 4.5. Multiple Values
let-value以及let*-values可以方便得同时制造多个变量绑定,例子如下:
(let-values ([(a b) (values 1 2)] [c (values 1 2 3)])
(list a b c))
(let*-values ([(a b) (values 1 2)] [(a b) (values b a)])
(list a b))
Section 4.6. Variable Definitions
有以下几种语法形式:
(define var expr)
(define var)
(define (var0 var1 ...) body1 body2 ...)
(define (var0 . varr) body1 body2 ...)
(define (var0 var1 var2 ... . varr) body1 body2 ...)
对于(define var expr)
,其expr不能返回多次。
对于(define var)
,其绑定的值是未定义的。
剩下的形式,是为了方便创建执行诀。
Section 4.7. Assignment
简单说,就是(set! var expr)
。用于更改一个既有变量绑定的内容。
(本篇完)