• 検索結果がありません。

3. その結果を表示する

3.10 制御構造 ( その 1)

let*は let と似て局所変数を用意します。最初の局所変数の初期値を求めると、その 値を次の局所変数の初期値を求めるときに使うことができる点が、letと違うところです。

例を見てみましょう。

> (define x 1)

#<unspecified>

> (define y 3)

#<unspecified>

> (let* ((x (+ y 1)) (y (* x 2))) (+ x y)) 12

(+ y 1) を評価すると

4

なので、これが x の初期値となります。次は (* x 2)を評価し

て y の初期値を決めますが 、ここでの xは最初の局所変数が使われます。ですので、yの 初期値は

4

となります。

letや let*は入れ子にして使うこともできます。次の式を評価すると、ど ういう結果 が得られるでしょうか

?

(let ((x 0)) (let ((x 1))

x))

答えは 1です。変数は、文面上で一番近い定義による束縛による値が使われますので、(let

((x 1) での定義が使われます。このため、 上の式の評価結果は 1になります。

実行例は次の通りです。

> (foo -1) non-zero

> (foo 0) zero

> (foo 68000) non-zero

このように ifは

} (if h条件式i

h1

i

h2i)

の形をしています。h条件式iを評価した結果が真

(

厳密いうと、#f以外

)

ならh1iを評

価し 、その値が if の値になります。そうでなければ h2i を評価し 、その値が if の値 になります。

h2iのない

4 (if h条件式i

hi)

の形も使うことができます19

この場合は h条件式i を評価した結果が真

(

厳密いうと、#f 以外

)

ならば hi を評価

し 、その値が ifの値になります。そうでなければ if 返される値は定められていません20

3.10.2 cond による場合分け

特殊形式 condは、複数の条件式をならべておき、真であるものに対応した式が選ばれ 評価され 、その値が返されます。

次の例を見てください。

(define (score n)

(cond ((<= n 50) 'fail) ((< n 70) 'poor) ((< n 80) 'fair)

(else 'excellent)))

19この形式での使い方は

Scheme

に必須な機能とは定められていません。そのために、処理系によっては この使い方ができない可能性もありますが 、ほとんどの処理系では用意されています。

20どのような値が返されるかは処理系に依存します。

この手続き scoreは、 引数nが

50

以下なら failを、

51

以上

70

未満なら poorを、

70

以上

80

未満なら fairを、

80

以上であれば excellent

返す手続きです。

実行例を見てみましょう

:

> (score 30) fail

> (score 67) poor

> (score 79) fair

> (score 96) excellent

一般に condは、以下の形をしています。

} (cond h1i

h2i

...

h

n

i)

つまり condは 、

cond-

(cond-clause)

と呼ばれる hi のならびです。それぞれの

hiは (h条件1i h1i ) の形をしています。

上から順に節の条件部 h条件iが評価され、その結果が真

(

厳密には #f 以外

)

ならその

節のhiが評価され 、最後の式の評価結果が cond の値になります。もし述語部が #f であれば次の節に移り、上と同様なことを続けます。

一番最後の節のh条件

n

iには、else を使うこともできます。どの述語も偽であった場 合に、この節の式 h

n

i を評価し 、この最後の式の評価結果を cond の評価結果とし ます。

condでは、節が書かれている順番に節の条件部が評価される、ということに十分注意し てください。たとえば 、上の例の節の順番を変えた手続き score2を見てください。

(define (score2 n)

(cond ((< n 80) 'fair)

((< n 70) 'poor) ((<= n 50) 'fail)

(else 'excellent))) では、これを実行してみます。

> (score2 30) fair

テストで

30

点をとってしまったにも関わらず成績は fair になり、上での場合と結果が 違っています。これは最初の節の条件が真なのでこういう結果になりました。

3.10.3 begin による式の逐次評価

特殊形式beginは、ならんだ複数の式を順に評価します。beginの評価結果は、最後の

式の評価結果となります。たとえば次のようになります。

> (define x 10)

#<unspecified>

> (define y 3)

#<unspecified>

> (begin (display "10 * 3 = ") (display (* 10 3)) (newline)) 10 * 3 = 30

#<unspecified>

となります。ここで手続きdisplay は、引数を表示する手続きです。また手続きnewline は、カーソル位置を次の行に移す

(

改行する

)

手続きです。

一般に beginは、

} (begin h1i

h2i

...

h

n

i)

の形をしていて、h1i,h2i h

n

iの順番で式が評価されます。そしてh

n

i の評価

結果が begin の値として返されます。

このように beginは、その本体にならんでいる式をすべて評価しますが 、最後の式の評 価結果以外は使われません。その本体にならんでいる式の評価結果そのものよりも、

画面にデータを表示する

変数に値を代入する

などをする式を順次実行するために使うのが主な目的です。式の評価で得られる結果の以 外の動作を副作用

(side eect)

といいます。たとえば set! はその式が返す値が目的では なく、変数の値を書き換えるという動作を目的として使っていますし 、手続き displayは 画面への表示を目的として使っています。

3.10.4 and or による式の逐次評価

特殊形式andと orは式のならびを順に評価してゆき、ある条件が成立すると途中で終 了します。

特殊形式andは一般に、

} (and h1i

h2i

...

h

n

i)

の形をしています。この特殊形式の実行は次のようにしておこなわれます。まず h1iを 評価します。もし式の評価結果が真

(

厳密には #f以外

)

ならば 、次の式h2iの評価をお

こないます。これを、式の評価結果が偽になるまで続けます。

もし最後のh

n

iまで評価結果が真ならば 、最後の式の評価結果が andの値として返さ れます。もし途中で評価結果が偽のものがあると、そこで and の実行を終了して、#f が andの値として返されます。

例を見てみましょう。

> (define x 10)

#<unspecified>

> (and (number? x) (> x 0) (+ x 1)) 11

この例では(number? x)を評価すると真で、次の (> x 0)の評価結果も真です。最後

に (+ x 1)が評価され、その結果は 11となり、これは偽ではないのでその値が andの値

として返されています。

では別の例を見てみましょう。

> (and (number? x) (> x 100) (+ x 1))

#f

この場合では (> x 100)が偽なので、その時点で andの実行が打ち切られます。そし て #f が andの値なっています。

andが特殊形式であることに注意してください。

(

単に論理積を計算するのではありませ ん。

)

もし特殊形式でなくて普通の手続きと同じように、実行の前にすべての引数が評価

された場合を考えましょう。上の例で変数xが数ではなくて記号だったら、引数評価のと

き、(+ x 1) の評価をしようとして、記号に

1

を加えることになってエラーになります。

特殊形式orは一般に、

} (or h1i

h2i

...

h

n

i)

の形をしています。特殊形式or の実行は次のようになります。まず h1

i を評価します。

もし評価結果が偽#f ならば 、次の式 h2iを評価します。同様にして、評価結果が偽 #f ならばさらに次の式を評価します。これを評価結果が偽である限り続けてゆきます。もし 最後まで評価結果が偽なら、orの値として偽が返されます。もし途中で評価結果が偽以外 のものがあれば or の実行を終了し 、その評価結果が or の値として返されます。or も単 なる論理和を計算するのではないことに注意しましょう。

例を見てみましょう。

> (define x -20)

#<unspecified>

> (if (or (< x 0) (> x 100)) "x < 0 or 100 < x" "else")

"x < 0 or 100 < x"

変数 x の値は -20なので、この例では (< x 0)が真となり、この値が or の値として返 されます。

> (if (or (= x 0) (> x 0)) "x >= 0" "x < 0")

"x < 0"

この例では、orに現れるどの式も評価結果が偽なのでor の値は#fとなり、ifにより "x

< 0"が返されています。