高校数学の窓過去問検索

Scheme入門 第4章 条件分岐 if 文


いくらコンピュータが「電子計算機」と訳されるからと言っても、ただ単純な計算させるだけではつまらん。今回はまともなプログラムには必須の if 文についてです。




if は次のように書きます。これは決まりです。ルールです。こればかりは変えられません。覚えてください。




(if 条件式 真の式 偽の式)




例:




(if (< 1 2)
(display "1は2より小さい")
(display "1は2より小さくない"))







プログラムを解析してみると、条件式(< 1 2) と、真の式(display "1は2より小さい") と、偽の式(display "1は2より小さくない") があって、if と全体を囲む括弧。




簡単ですね。if 文の意味は、条件式 が真の場合は 真の式 が実行され、条件式 が偽の場合は 偽の式 が実行されるというものです。実行されない方の式は、つまり、実行されません。偽の式 は必要でなければ省略できます。




次のような書き方も出来ます。




(display (if (< 1 2) "1は2より小さい" "1は2より小さくない"))




まず (if (< 1 2) "1は2より小さい" "1は2より小さくない") ですが、条件式の (< 1 2) は真ですので、if 文全体としては "1は2より小さい" という結果になります。これで if 文を置き換えてみますと、




(display "1は2より小さい")




となるので、display によって「1は2より小さい」と表示されます。1行に書くと見難い場合は次のように行を分けてみるとどうでしょう。




(display
(if (< 1 2)
"1は2より小さい"
"1は2より小さくない"))





どっちも見難い?まぁこればかりは慣れです。このような if の使い方は、知ってる人は C 言語の三項演算子を思い浮かべれば良いかな(※1)?ところで次のような使い方も出来ます。




(display ((if #t + *) 1 2))






まず (if #t + *) ですが、条件式は真なので、if 全体は + になります。そうすると




(display (+ 1 2))




ということになるので、結果は 3 です。妙な感じですが、こういう使い方も出来るという一例で。




もひとつ最後に。if の 真の式偽の式 に複数の式を書きたい場合。C 言語でいうところの「複文」というやつですが、Scheme では構文 begin を使って複数の式をひとつにまとめます。




(if (< 1 2)
(begin
(display "1は2より")
(display "小さい"))
(begin
(display "1は2より")
(display "小さくない")))





だんだん括弧が多くなって来ました。括弧の数を数えるなんてことはやってられませんので、インデントの付け方が他の言語以上に重要になります(※2)。いくらフリースタイルだからって第1章に示したぐちゃぐちゃな書き方みたいにならないよう、くれぐれも気を付けてください。




第4章・完




第5章へ






    ※1:しかしながら、世界で初めていわゆるif-then-elseと言う形式の構文(条件分岐)を発明したのは、実はSchemeの先祖であるLispである。Lisp以前には条件分岐の為の構文は存在しなかったし、かつLisp以前に存在していた高級言語はFortranしか無かった。

    ※2:とは言っても、DrSchemeのエディタにはオートインデント機能があるので、それ程神経質にならなくても良い。自分の好きな場所で[Enter]キーを叩けば同一の計算式内の引数は同じ位置まで自動で字下げしてくれる。
    例えば、例示されているコードも



    だろうが、



    だろうが、構わない。
    要は「自分がシックリと来る位置」で[Enter]キーを叩けば、後は全てまとめてDrSchemeのエディタが面倒を見てくれる。
    大事なのは「同一のレベルにある引数の行頭が揃っている事」であり、そのテのツマラナイ作業はエディタ任せで構わないのだ。
    なお、ソースコードは「インデントで読んで行く」と言うのが現代的なプログラミングの流儀で、これはC言語だろうが何だろうが基本は変わらない(例外がポピュラーな例では2つだけあるが、それは後述する)。
    Schemeは「括弧の数が多すぎる」と批判される事もあるが、実は書いてる方は「括弧の数の帳尻で」ソースを読んでるワケではない。なんせ、DrSchemeのエディタをはじめとして、現代的なプログラミング専用のエディタは

    「どの左括弧(通称:カッコ)とどの右括弧(通称:コッカ)が対応しているのか」

    教えてくれるので、「カッコとコッカの帳尻合わせ」で頭を悩ます必要は無いのだ。逆に言うと、マトモなエディタが無ければSchemeではプログラムが書けない、とも言えるが、それはどの言語でも多かれ少なかれ同じである。
    むしろ、Schemeの括弧の問題点としては、やはりインデント絡みで、プログラムを修正して括弧の数が増えた(または減った)時、ソース全体の見栄えがグチャクチャになってインデントをやり直さなければならない時である。
    しかしながら、これもDrSchemeの場合、対策は万全で、インデントをやり直さなければならない箇所をマウスで選択した後、[Scheme]プルダウンメニューから[再インデント]を選べば自動でインデントをやり直してくれる。






    DrSchemeの[再インデント]プルダウンメニュー。
    キーボードショートカットを意に介さないのだったら、適度に[Ctrl]+[i]を押せばソースコードの[すべてを再インデント]してくれる。ある程度プログラミング慣れをしてるんだったら、こっちのショートカットの方がお薦め。


    いずれにせよ、「インデントで読む」「インデントで書く」と言うのは現代のプログラミングでは普遍的な「大事な習慣」である。


      弟子が尋ねた。「先生、私は先生がカッコをまるで魔術師の ように扱っているのを常々敬服しています。どうすれば先生のようになれ るのでしょうか?」
      師「えっ? カッコ? あ、そうか。そんなものもあったな。いやあ、 すっかり忘れておったわ」
      竹内郁雄氏-bit 2000 年 5月号より



    さて、その「インデントで読み/書きをする」と言う一般的なプログラムの読解法、と言う大事な習慣を全く考慮していないのがご存知BASIC言語である。従って、ハッキリ言うが、「基礎的な習慣を身につけさせない」と言う意味では「プログラミング初心者用言語」としては全く失格である。BASICを卒業してC言語等を勉強するハメになった場合、「新たに普遍的な習慣を身につけなければならない」と言う意味では二度手間以外の何物でも無い。
    メジャーどころの言語では、基本的にFortranとBASICの二つだけが「行指向型」と言われるプログラミング言語のスタイルをとっている。ソースコードは「インデント」ではなく「行」で書いて読んで考えるのだ。その為にFortranとBASICのソースコードには不可解な「行番号」なるモノが付いている(現代では必須では無くなってはいるが)。
    もちろん、BASICを卒業した後に「Fortranを勉強すべき」なら問題が無いが、その先は無い。教育の普遍性を考えるのならあまり賢い選択肢とは言えないだろう。
    では、何故FortranとBASICの2つだけが「行指向」でその他の言語はそうじゃないのだろう?その秘密はこれらの言語の登場年代に隠れている。
    C言語が登場したのは1972年、Schemeが登場したのが1975年。一方Fortranが登場したのが1954年。BASICが登場したのがその10年後の1964年。何か気づかないだろうか?


    「う〜ん……。C言語もSchemeも70年代に登場したけど、FortranもBASICもそれ以前に生まれた?それくらいしか分かんないや。」


    それが実は正解である。
    元々70年代よりも前ではコンピュータの出力、と言うのは今考えるより遥に貧弱で、出力表示は「1行づつ」しか行えなかった。従ってプログラムの編集作業も「1行づつ」しか行えなかったのである。
    想像して欲しいのだが、例えば高校数学の窓にブラウザでアクセスして、そのコンテンツを「1行づつ」しか表示出来なかったとしたらどうだろう?「信じられない!!!メンド臭い!!!」と思うだろう。事実、70年代以前のコンピュータとはそう言うモノだったのである。FortranもBASICも「そう言う環境で」設計された言語なのである。要するに「行指向」にならざるを得なかったのだ。そして、目的とする「行」を素早く検索/表示させる為、インデックスとして「行番号」が存在してたのである。
    一方、やっと70年代に入って、少なくともテキストファイルの内容をディスプレイ上にある程度「一括表示」する事が可能となった。そしてそれに従って、プログラムを編集するエディタも「画面単位」で編集する事が可能となる。70年代以前はWindowsで言う「メモ帳」は持てなかったのだが、70年代に入ってやっと「メモ帳」らしきモノを手に入れる。こう言う種類の「ファイルを開いて画面として表示出来る」テキストエディタを、古い呼び方で「スクリーンエディタ」と呼ぶ(反面、「行単位で表示/編集」するエディタを「ラインエディタ」と呼ぶ)。
    70年代以降に登場したプログラミング言語は、この「スクリーンエディタ」を用いて編集される事を念頭に於いて設計された。つまり「行番号よ、さようなら」と言うワケである。
    ツールの発達が人間の思考様式を変化させる、と言うような事柄は歴史的にはままある事だが、近年ではこの「ラインエディット」→「スクリーンエディット」への移行、と言うのはプログラミングに於いては革命的だったと言えよう。コンピュータが「全画面表示」と言う技術を手に入れてからプログラミング言語設計の発想は根本的に変わったのである。「構造化プログラミング」と言う発想も、出力/編集環境の進歩が無ければ出てこなかっただろう。
    良く、「BASICは行番号があるから、フローが読みやすく初心者向きと言える」等と言う意見も聞くが、実はこれは勘違いで、行指向になったのは単に設計当時のコンピュータの「出力の限界、編集の限界」があったからで、別段「初心者の為に設計したから」ああなったワケではない。むしろ、「1行1命令」と言うのは今の常識からすると無茶苦茶である。
    さて、パソコンの能力が貧弱で「BASICくらいしか動かせなかった」80年代初頭だったらいざ知らず、ハードウェアの能力も無茶苦茶進歩した2008年現在、「60年代以前の流儀を引き摺った過去の遺物」を勉強する事が果たして初心者の為になるのだろうか?








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 コメント: