プログラミングGauche > 第2部 Gaucheの基礎練習 > 第8章 真偽値と条件判断 > コラム: すべて式である


[Prev] [Next] [Up] [Contents][フレーム表示] [フレーム解除

コラム: すべて式である 応援する 

Schemeでは計算というのは式の値を求めることです。

Schemeの式は以下のとおりに表現されているものです。

  1. ひとつの塊(シンボルおよびリテラル)として表現されるもの。 この構文のことをアトムということがあります
  2. 複数の式を括弧(())で囲って表現されるもの。 この構文のことをリストということがあります
  • 1. により、mapstring=?*-53.14"The Wizard Book"#\a はどれも式です。
  • 2. により、(- 1 (* 2 3))(string->list (string-map char-upcase "wikiwiki")) も式です。

式が表す値に名前をつけることを定義といいます。Schemeでは式が表す値に 名前を付けることによって、複雑な構成の式をひとつのものとして抽象化して 表現することができます。

すべて式とはどういうことか

たとえば、Schemeではifは制御構造ではありません。 ifは式なので値を返します

aに「bの絶対値」を加算するプログラムを考えて見ましょう。 絶対値を求める手続きabsを使わないとすると、

 (define (a-plus-abs-b a b)
   (if (>= b 0)
        (+ a b)
        (- a b))) 

と書けます。これはif式全体の値が手続き適用したときの値として返されま す。また、if式は値を返すので、

 (define (a-plus-abs-b a b)
   (+ a (if (>= b 0)
            b
            (- b)) ))

のとおりにbの値の正負によって、bか-bを返しています。 さらにSchemeでは手続きそのものも値ですので、手続きを値として返す 式を書けます。以下の定義でif式はbが正の値なら + 手続きを、 負の値なら - 手続きを返しています。

 (define (a-plus-abs-b a b)
   ((if (> b 0)
          +
          -) a b))

例えばaが23、bが16ならば、

((if (> 16 0) + -) 23 16)
↓
(+ 23 16)
↓
39

aが12、bが-74ならば、

((if (> -74 0) + -) 12 -74)
↓
(- 12 -74)
↓
86

と計算できます。

代入(assignment)がなくても計算はできる

Schemeにおいて計算する対象がすべて式であるなら、代入文(assignment statement)はないということ になります。なぜなら、すべて式なのであれば、代入を使わなくても置き換え(substitution)モデルで説明可能だからです。

代入文がなくてプログラムが書けるかを確かめてみましょう。

1から指定した上限nまでの整数の和をもとめる計算を考えてみましょう。

 1 + 2 + ... + (n-1) + n

このプログラムを書くのに代入文が欲しいですか。 こんな風に計算させようとしていますか。

  1. sに0を代入
  2. iに1を代入
  3. iがnを超えない間4 〜 5を実行、nを超えたら6へ
  4. s + iを計算してその結果をsに代入
  5. i + 1を計算してその結果をiに代入
  6. sの値を印字

なるほど。これで計算できる気がします。でもこれで本当に欲しい ものが手にはいるかどうかは、よくよく読んで検討しなければなりません。

こんな風に欲しいものを「いかにして」得るかの手順を考えるのではなくて、 もっと単純に考えることもできます。これを行う手続きをsumとしましょう。 こんな風に考えます。

  1. nが 1のとき、(sum n) の値は1
  2. nが 1より大きいとき、(sum n)の値は、ひとつ手前(n-1)までの和 (すなわち (sum (- n 1))) とnとの和

これを書くと、

  (define (sum n)
    (if (= n 1)
        1
        (+ (sum (- n 1)) n)))

欲しいものが「何か」を書いただけです。 でも欲しいものはちゃんと書けているということが分ります。 どこにも代入は必要ありませんでした。

ではなぜ、最初は代入が必要だと思ったのでしょう。 「プログラムは計算の手順を書いたもの」という先入観がどこかに ありませんでしたか。

ここでは整数和の例で確かめてみましたが、 一般的にそれ以外の計算でも多くの場合,代入を使わないで分りやすく プログラミングすることができます。

とはいうものの,代入を使うのが本質的だと思われている処理を簡単に扱うために Schemeではちゃんと代入を行う手続きが使えるようになっています.

(山下 伸夫)


[Prev] [Next] [Up] [Contents][フレーム表示] [フレーム解除

このサイトについて|ヘルプ|Q&A|個人情報保護|プライバシーポリシー|利用規約|コメント・トラックバック規約|削除規程|広告掲載
Copyright (c) 2005-2007 Time Intermedia Corporation