# 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 ```
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up