scheme は関数型言語 lisp の方言の一つである。
関数型言語の基本:
知能情報工学科の計算機には、DrScheme がインストールされている。 DrScheme は、Scheme のプログラミング環境の一種である。 ここがホームページである:http://www.plt-scheme.org/ Windows用もある。
演習のために準備しよう。コンソール上で以下を実行しよう。
mkdir -p ~/2009-Lect-3/Scheme/ (ディレクトリの作成) cd ~/2009-Lect-3/Scheme (演習場所に移動) drscheme (Scheme の起動) |
以下に主な操作方法を示す。
起動方法 | コンソール上で |
---|---|
ウインドウ | デフォルトでは、メニュー行、ツールバー、および、2つの白いエリアがある |
上のエリア:式を定義するエリア(Definitions) | |
下のエリア:対話的に式を評価(実行)するエリア(Interactions) | |
マニュアル | メニューの中の「ヘルプ」の中の「ヘルプデスク」より検索が可能 |
プログラムの作成 | 定義エリアに書き込む |
プログラムの実行 | 実行(Run)ボタンを押した後、対話エリアで、式を入力する(たとえば、関数に具体的な値を与える) |
プログラムの保存 | メニューの中の「ファイル」の中の「定義の保存」を選択する※ |
プログラムの読み込み | メニューの中の「ファイル」の中の「開く」を選択する |
終了方法 | メニューの中の「ファイル」の中の「Quit」を選択する |
※ この選択で定義エリアのみを保存する。対話エリアの保存は、「その他の保存」より行う。
式には次の種類がある:
評価の方法:
主な定数を以下に示す。
※ シンボルと文字列は、実体が共通か否かという点で異なる。
以下の定数である式を評価しよう。対話エリアに入力し、Enterキーを押して、返り値を確認しよう。
> 100 ⇒ 100 が返り値となる。 > 3/4 ⇒ 分数を評価すると,3/4が返り値となる。 言語(ツールバー)の選択によっては実数で返り値が表示される。 > 'hello ⇒ シンボルとしての hello が返り値となる。 |
実は、演算子や関数名も評価できる。対話エリアで返り値を確認しよう。
> + ⇒ 足し算の本体である #<procedure:+> が返り値となる。 > sin ⇒ 正弦関数の本体である #<procedure:sin> が返り値となる。 |
コンビネーションは、以下の形式となっている。
(〈式1〉 〈式2〉 〈式3〉 〈式4〉… 〈式n〉) |
〈式1〉のことを、最左部分式と呼ぶ。コンビネーションの評価とは、〈式1〉から〈式n〉までを個別に評価した後、最左部分式の評価結果(式1の返り値)に、残りの部分式の評価結果を渡して評価する。このとき、最左部分式の評価結果は #<procedure> でなければならない。
対話エリア 上で、「コンビネーション」の式を評価してみよう。
> (- 5) ⇒ 単項演算 > (+ 1 2) ⇒ 2項演算 > (sqrt 2) ⇒ 組み込み関数。√2 のこと > (+ (* 2 3) 4) ⇒ 中置記法では「 2 * 3 + 4」 > (* (+ 1 2) (- 3 (/ 4 5))) ⇒ 中置記法では「(1 + 2) * (3 - 4 / 5)」 > (sin (/ 3.141592653589793 2)) ⇒ 引数部に式を与えている。数学の記法では、sin(π/2) のこと |
特殊形式は、記述形式は、コンビネーションと同様であるが、最左部分式が特定の語である。たとえば、次のものがある。
対話エリア上で、「特殊形式」の式を評価してみよう。
> (define x 100) ⇒ 100 に x という名前を付ける。 > (set! x 200) ⇒ x の指す対象を 200 とする(詳細は後の回で演習します)。 > (if (= x 100) 'ok 'ng) ⇒ 〈式2〉の評価結果が #f でなければ〈式3〉を評価し、#f ならば〈式4〉を評価する(詳細は後の回で演習します)。 > (lambda (x) (* x 3)) ⇒ 引数 x をとり、x * 3 を返す関数を表す(詳細は後の回で演習します)。 |
define で作成した名前は、評価をすると、指している対象を返す。
対話エリア 上で、「変数」の作成とその評価をしてみよう。
> (define x 100) ⇒ 特殊形式の評価。「100」の評価結果に「x」という名前を付けた。 > x ⇒ 変数の評価。変数 x を評価すると、対応する式が返り値となる。 > (define san (+ 1 2)) ⇒ 特殊形式の評価。「(+ 1 2)」の評価結果に san という名前を付けた。 つまり、「3」に「san」という名前を付けた。 > san ⇒ 変数の評価。変数 san を評価すると、対応する式(定数 3)が返り値となる。 > (define tasu +) ⇒ 特殊形式の評価。「+」の評価結果(#<procedure:+>)に、tasu という名前を付けた。 > (tasu 1 2) ⇒ 「コンビネーション」の評価。 > tasu ⇒ 変数の評価。 > (tasu x san) ⇒ 全体はコンビネーションの評価。〈式1〉から〈式3〉までをそれぞれ評価して、 〈式2〉と〈式3〉の評価結果を〈式1〉の評価結果に渡して評価してもらう。 つまり、100 と 3 を #<procedure:+> に評価してもらう。 |
果物の名前と価格を定義し、その名前を使って、果物の代金を計算しよう。
価格は次のように設定しよう。
apple | 110 |
---|---|
orange | 90 |
pineapple | 230 |
peach | 190 |
例として、apple 3つ、orange 5つ、pineapple 1つ、peach 5つの代金の合計を計算しよう。
(define apple 110) (define orange 90) (define pineapple 230) (define peach 190) |
> (+ (* apple 3) (* orange 5) (* pineapple 1) (* peach 5)) |
上記の定数の定義をファイル「prac0605.scm」に保存しよう。また、いったんdrscheme を終了し、再び起動して、定義ファイルを開いてみよう。
練習5の続きとする。贈り物用のフルーツセット(giftbox)には、melonが1つ、appleが5つ、orangeが3つ入っている。ここで、melon は単価が 800 円とする。giftbox の代金は、入っている果物の代金と箱代(box)50円の合計とする。giftbox の代金を定義しよう。
お得用フルーツセット(specialbox)には、1割引の桃が3つ、定価のパイナップルが1つ、2割引のオレンジが5つ入っている。箱代を30円とする。specialbox の代金はそれらの果物の代金と箱代の合計とする。specialbox の代金を定義しよう。
以上の定義を prac0606.scm に保存しよう。
tan の逆関数は atan である。tan(π/4)は1になるので、atan(1)はπ/4となる。そこで、atan を利用して、円周率 3.141592.... に pi と名前を付けてみよう。