letrec

如果希望在一个结构中,支持不同procedure之间的互递归,即在定义之后,生成局部并行处理的block,使用letrec

1
2
3
4
5
6
7
(letrec ((local-even? (lambda (n)
(if (= n 0) #t
(local-odd? (- n 1)))))
(local-odd? (lambda (n)
(if (= n 0) #f
(local-even? (- n 1))))))
(list (local-even? 23) (local-odd? 23)))

let

使用letrec定义递归过程可以实现循环,显示10到1的降序列

1
2
3
4
5
6
7
(letrec ((countdown (lambda (i)
(if (= i 0) 'liftoff
(begin
(display i)
(newline)
(countdown (- i 1)))))))
(countdown 10))

递归函数只在函数外部一个地方外部调用,使用Named let

1
2
(let name ((var expr) ...)
body1 body2 ...)

相当于Python Namedtuple,给let语句块命名,分配了变量指针

迭代

Scheme采用尾递归的方式,在递归调用时,不增减堆栈数量,而是覆盖栈帧。由于父过程在活动期间内,只在尾部进行调用自身,所以可以对栈帧进行覆盖。

尽管去写递归吧,这在Scheme中是安全的

自定义过程映射列表 $\Delta$

Sheme支持一种特殊类型的迭代,对于列表的每一个元素,都去执行

  1. map
  2. for-each

map支持返回值

1
2
(map add2 '(1 2 3))
; ==> (3 4 5)

for-each不支持返回值,只产生求值过程中的副作用

1
2
(for-each display
(list "one " "two " "buckle my shoe"))

多参数程序

(map + '(1 2 3) '(10 20 30))
; ==> (11 22 33)