今日から第4章だ。
この章の関数名には、白抜きの+、-みたいな、ASCII にはない文字が出てくる。ここは、p.62 の脚注にしたがって、o+ とか o- と書くようにする。o はたぶん operator の o。
下準備
n に1と足す add1 と、n から1を引く sub1 を定義しておく。
(define add1 (lambda (n) (+ n 1))) (define sub1 (lambda (n) (- n 1)))
(白抜きの)+
まずは、白抜きの+、すなわち o+。これは2つの数を引数にとって1つの数を返す関数で、要するに足し算だ。ヒントには、zoro?、add1 と sub1 を使おうと書いてある。ま、このくらいは簡単に書ける。
(define add1 (lambda (n) (+ n 1))) (define sub1 (lambda (n) (- n 1))) (define o+ (lambda (n m) (cond ((zero? m) n) (else (add1 (o+ n (sub1 m))))))) (print (o+ 1 3)) (print (o+ 10 5))
試してみよう。
^o^ > gosh add.scm 4 15
OKのようだ。
(白抜きの)-
次は、白抜きの-、すなわち o-。これは引き算だ。これも簡単。
(define add1 (lambda (n) (+ n 1))) (define sub1 (lambda (n) (- n 1))) (define o- (lambda (n m) (cond ((zero? m) n) (else (sub1 (o+ n (sub1 m))))))) (print (o+ 3 1 )) (print (o+ 10 5))
実行:
^o^ > gosh sub.scm 2 5
こっちもOK。
2つの関数に共通すること
o+ と o- の2つの関数に共通するのは、cond の条件が zero? と else であることと、(sub1 m) で再帰していることだ。3章でラットの再帰をしたとき、最終条件が null? だったのと違って、数の再帰では zero? が最終条件となる。また、cdr で再帰する代わりに sub1 で再帰している。ラットの場合は、空になるまでひとつずつ見ていくのに対して、数の場合には 0 になるまで 1 ずつ減らしていくのだな。
第1の戒律
(改訂版)
アトムのリスト lat を再帰するときは、2つの質問をすべし。すなわち、(null? lat) と else なり。
数 n を再帰するときは、2つの質問をすべし。すなわち (zero? n) と else なり。