プログラミング再入門

プログラミングをもう一度ちゃんと勉強する読書ノート

Scheme手習い 第4章 数遊び(その1)

この章では数の扱いを習います。元々Scheme(あるいはR5RS)として算術関数は定義されていますが、それを改めて自前で再帰的に定義します。

ノート:

一応、各々の数字がアトムか否かを確認する。

> (atom? 14)
#t
> (atom? -3)
#t
> (atom? 3.1415)
#t
> 
add1、sub1

add1の定義は脚注に提示されているが、本書ではadd1は組み込み関数として扱われている。

> (let ((n 67))
    (add1 n))
68
> (add1 67)
68
> 

引数が数のときは「ここで、nは67です」と言う必要はありません。(because we don't need to say "where n is 67" when the argument is a number.)

正確には分からないが、quoteする必要がないと言う事と関連しているのかも知れない。

sub1も同様に組み込み関数として扱われている。

> (let ((n 5))
    (sub1 n))
4
> (sub1 0)
-1
> 

本書では負の数は扱わないと言う事なので、(sub1 0)の答えは無いと書いてあるが、実際の実装系では当然-1と言う答えになる。

zero?

zero?はR5RSで定義されている。

> (zero? 0)
#t
> (zero? 1492)
#f
> 

本書ではadd1、sub1、zero?を用いて自前の加算演算関数を定義する。元々ある加算演算関数と重複してしまわない様に本では白抜きの+を使用しているが、UTFの文字表から適当な字が見つからないので、⊕で代用する。DrRacketではUTFの文字もちゃんと認識してくれる。
m+nの定義:

  1. mが0であれば、n
  2. そうでなければ、n + (m-1)に1を加えた数

はてなのpre記法では表示出来ないようなので、ここでは全角の+で表記しておく。DrRacketのプログラム上でも全角の+は使える、本物の+と見分けが付きにくかったので、自分のプログラム上では⊕を使用している。

> ( 46 12)
58
> 

同様に減算関数。
m-nの定義

  1. mが0であれば、n
  2. そうでなければ、n - (m-1)から1引いた数

同様にここでは全角のーで表記しておく。

> ( 14 3)
11
> ( 17 9)
8
> ( 18 25)
-7
>
タップ(タプル)

数のリストのことをタップ(あるいはタプル)と呼びましょう。(Yes: tup is short for tupple.)

「あるいは」と書いてあるが、タップはタプルの短縮形としている。

addtup

タップに含まれる数の合計を求める関数。
addtupの定義:

  1. 数だけからなるリストtupに適用し、「各要素の合計」を意味する。
  2. tupが空であれば、0
  3. 空でなければ、tupの先頭要素の数とtupの残りの要素にaddtupを適用した数の合計

この定義をちゃんとプログラムとして表示すると:

(define addtup
  (lambda (tup)
    (cond
      ((null? tup) 0)
      (else (⊕ (car tup) (addtup (cdr tup)))))))

評価してみる。

> (addtup '(3 5 2 8))
18
> (addtup '(15 6 7 12 3))
43
> 
×

これは*と見間違える事はないので全角の×を使う。

> (× 5 3)
15
> (× 13 4)
52
> (× 12 3)
36
> 

第5の戒律:…行を終えるときに常に値として0を用うべし。(always use 0 for the value of the terminating line,)…

「行を終えるとき」ではなく「再帰を終える行に於いて」と解釈する。

tup+

最初の定義で評価してみる。

> (tup+ '(3 6 9 11 4) '(8 5 2 0 7))
(11 11 11 11 11)
> (tup+ '(2 3) '(4 6))
(6 9)
> (tup+ '(3 7) '(4 6))
(7 13)
> 

この定義では二つのタップの要素数が同じじゃないとエラーを起こす。

> (tup+ '(3 7) '(4 6 8 1))
. . mcar: expects argument of type <mutable-pair>; given ()
> 

新しい定義を評価してみる。

> (tup+ '(3 7) '(4 6 8 1))
(7 13 8 1)
>