---
# System prepended metadata

title: scheme言語

---

# scheme言語
# ・Chapter4

**【条件式】**
すべての言語と同様に、Schemeには条件式があります。 基本フォームはifです。
```
(if test-expression
    then-branch
    else-branch)
```
test-expressionが評価されて真(すなわち、#f以外の値)になれば、 “then”の枝が評価されます。さもなければ、“else”の枝が評価されます。 “else”の枝はなくてもかまいません。
```
(define p 80)

(if (> p 70) 
    'safe
    'unsafe)
=>  safe 

(if (< p 90)
    'low-pressure) ;no ``else'' branch
=>  low-pressure 
```
Schemeでは利便のために他にも条件式フォームが用意されています。 これらはすべて、if式に展開されるマクロ(chap 8)として 定義することができます。

**4.1 whenとunless**
whenとunlessはひとつの枝(“then”あるいは“else”の枝)しかない 基本条件式が必要なときに便利です。
```
(when (< (pressure tube) 60)
   (open-valve tube)
   (attach floor-pump tube)
   (depress floor-pump 5)
   (detach floor-pump tube)
   (close-valve tube))
```
tubeのpressureが60未満と仮定すると、この条件式は floor-pumpをtubeに取り付け、5回押します (attachとdepressはなにか適当な手続きです)。

同じプログラムをifを使うと次のようになります。
```
(if (< (pressure tube) 60)
    (begin
      (open-valve tube)
      (attach floor-pump tube)
      (depress floor-pump 5)
      (detach floor-pump tube)
      (close-valve tube)))
```
whenの枝は暗黙のbeginであり、一方、ifでは どちらかのブランチに2つ以上フォームがあるときには 明示的なbeginが必要です。

同じ振舞いをunlessをつかって書けば以下のようになります。
```
(unless (>= (pressure tube) 60)
   (open-valve tube)
   (attach floor-pump tube)
   (depress floor-pump 5)
   (detach floor-pump tube)
   (close-valve tube))
```
すべてのSchemeがwhenとunlessを用意しているわけではありません。 おつかいのSchemeになければ、マクロ(8章参照)として定義できます。

**4.2 cond**
condフォームは入れ子になったif式を表現するのに便利です。 最後以外の“else”の枝には新しいifが導入されます。したがって、
```
(if (char<? c #\c) -1
    (if (char=? c #\c) 0
        1))
```
はcondをつかって、次のように書けます。
```
(cond ((char<? c #\c) -1)
      ((char=? c #\c) 0)
      (else 1))
```
このように、condはマルチブランチの条件式です。 各節にはテストとそれに結びつくアクションがあります。 最初に成功したテストがそれに結びついたアクションを起します。 最後のelse節はどのテストも成功しなかった場合に選択されます。

condのアクションは暗黙のbeginです。

**4.3 case**
condの特別な場合にはcase式で圧縮した表現にできます。 これはすべてのテストが所属テストの場合です。
```
(case c
  ((#\a) 1)
  ((#\b) 2)
  ((#\c) 3)
  (else 4))
=>  3
```
cの値を先頭にもつ節が選択されます。

**4.4 andとor**
Schemeには論理積(“and”)と論理和(“or”)に対応するスペシャルフォームが 用意されています(2.1.1節で見た否定のnotは手続きです)。

スペシャルフォームandはすべてのサブフォームが真ならば真を返します。 実際に返ってくる値は最後のサブフォームの値です。サブフォームのひとつでも 偽であれば、andは#fを返します。
```
(and 1 2)  =>  2
(and #f 1) =>  #f
```
スペシャルフォームorは最初に真になったサブフォームの値を返します。 もし、すべてのサブフォームが偽ならばorは#fを返します。
```
(or 1 2)  =>  1
(or #f 1) =>  1
```
and、orはともにサブフォームを左から右へ評価します。 結果が決りしだい返すことができるのでandとorはのこりの サブフォームを無視することがあります。
```
(and 1 #f expression-guaranteed-to-cause-error)
=>  #f

(or 1 #f expression-guaranteed-to-cause-error)
=>  1
```