高校数学の窓過去問検索

Scheme入門 第3章 真偽を見極める


第3章では、「真」「偽」についてのお話。真とは要するに true のことで、偽とは false のことです。第2章で以下のような手続きを紹介だけしました。




  • = 等しい

  • < より大きい

  • > より小さい

  • <= 以上

  • >= 以下




実際に試してみましょう・・・ではまず、実用的には全く意味のないことですが、1 と 1 が等しいことを確認してみます。





(display (= 1 1))




実行すると次のように出力されます。





#t




等しくないときも試してみましょう。





(display (= 1 2))




実行すると次のように表示されます。





#f




この #t#f
「真」「偽」と呼ばれる者たちです。正しいときは #t(真)、正しくないときは #f(偽)と考えれば良いです。ちなみに (display #t) とかやると #tが表示されるのは言うまでもなく。




さて、この真偽値を返す手続きは、他にも色々あります。例えば・・・




  • zero? 値が0であるか調べる

  • boolean? 値が真偽値であるか調べる

  • string? 値が文字列であるか調べる

  • number? 値が数値であるか調べる

  • integer? 値が整数であるか調べる

  • eq? 値が等しいか調べる

  • eqv? 値が等しいか調べる

  • equal? 値が等しいか調べる




例えば 1.5 は数値なので number?#t を返しますが、整数ではありませんので integer?#f を返します。





(display (number? 1.5))
(display (integer? 1.5))





実行結果:





#t#f




ところで、値が等しいかどうかを調べる手続きが、なんと3つもあります。eq?, eqv?, equal? です。さらに = も値が等しいかを調べる手続きでした。どのように使い分けるのでしょう?




まず第一に = は数値専用です。文字列とか真偽値の比較には使えません。それに対して eq?, eqv?, equal? はどんな値の比較も出来ますが、数値を比較する場合はやはり = を使うべきです。例えば 1 と 1.0 を比較すると、= は期待通り #t を返しますが、eq?, eqv?, equal?#f を返してしまいます。型が異なるためです。要するに数値は = で比較しろということです(※1)。




次に eq? ですが、これはオブジェクトのアドレスが等しいかどうかを比較する手続きです。保持している値が等しかろうが、全く関係ありません。同一のオブジェクトを指しているかどうかだけを判定します。




eqv? は、普通に値の比較をします。ただしリスト、ベクタ、文字列、構造体のように大きなオブジェクトは、その中身までは比較しません。それ以外の値については、普通に値が比較されます。そもそも値の型が異なる場合は、比較する以前に #f を返します。




equal? は、リスト、ベクタ、文字列、構造体のようなオブジェクトも、その中身まで再帰的に比較します。そのため比較に時間がかかったり、循環参照になっている場合に比較が終了しなかったりします。それ以外は eqv? と同じです。




リストとかベクタとかまだ話してない内容が出てきてますが、ふぅんそういうのもあるんだぁ程度で。おいおい詳しく解説していくことでしょう(※2)。




第3章・完




第4章へ






    ※1:余談だが、数学で言う=記号は悩ましい。あまり普段は意識しないが、数学では=は"等しい"と言う意味と"代入"と言う意味と両方に使えてしまう。数学では珍しく、2つの意味を持つ非常に便利な記号なのだ。人間は「文脈で判断してくれる」ので実用上は問題が生じない。
    一方、コンピュータの世界では"代入"と言う行為と"等しい"と言う意味が丸っきり違う以上別の記号を用意せざるを得ない。真偽判定用記号をどうするのか?と言う問題が生じてくるのだ。
    プログラミング言語設計に於ける一つの解決策は"代入"と言う行為に付いては=で表し、"真偽判定"を表す場合に==と言う記号を使う、と言うテだ。これはBASICをはじめ結構なプログラミング言語で使われる手法である。
    もう一つの解決策が"真偽判定"を=で表し、"代入"を別の記号に表す、と言うテ。統計解析言語RやSchemeはこっち側に属する。
    Schemeの場合、数学的な意味でも工学的な意味でも数値の変数への代入はset!を用いる。しかも第5章で示唆されているように、実はSchemeでは"代入"行為は基本的に推奨されていない。使わないなら使わないに越したことが無いのだ。


    「代入無しで数式を計算する?」


    と聞くと驚くかもしれないが、数学的な意味での"代入"はコンピュータ上では「メモリの書き換え」で実現される。しかしながらSchemeはそう言う必要性が生じる設計は成されてなく、また、代入自体が存在しなくても数式の計算が出来る事は数学的に保障されている。
    Schemeで「代入」代わりに使われるのが、平たく言うと「参照」と言う方式で、それを実現するのが第5章で扱われているdefine第12章で扱われている局所変数である。
    いずれにせよ、そう言う理論上の背景もあり、Schemeでは=が"代入"なのか"真偽判定"なのか、設計上の議論をする必要性が生じないのである。

    ※2:とか言いながら、この講座ではベクタは全く出てこないまま終了してしまう。
    ベクタに付いて知りたい人はココを後で参照して欲しい。
    なお、構造体に付いては処理系依存が大きい部分なので、取り扱わない。









DrScheme






  1. DrScheme での Language Pack の選択

  2. Scheme の単純な式「(+ 3 2)」, 「(- 10 4)」

  3. Scheme の単純な式(括弧の入れ子)

  4. Scheme の単純な式 (DrScheme の定義ウインドウ)

  5. 関数 area-of-disk の定義と,関数適用

  6. 関数 area-of-disk,変数 PI の定義と,関数適用(1)

  7. 関数 area-of-disk,変数 PI の定義と,関数適用(2)


0 コメント: