プログラミング言語I

scheme

基本

アトムとリスト

アトム

数またはシンボル

数とは?

整数、小数、分数、複素数 など

整数の例

1,2,3,0, -100 ,11234 などなど

小数の例

1.25 , -3.8888 , 2.23608 などなど

分数の例

1/2, 4/5, 254/77 などなど

複素数の例

1.25+5i ,0+i などなど

シンボル

シンボルの例

apple , banana , cake などなど

シンボル

辞書にのっているような単語である必要はない

a123, aweoaighhw, _awf* とかもシンボル

アトム

数またはシンボル

リスト

カッコで囲まれたデータ

リストの例

(apple)

リストの例

(apple orange cake )

リストの要素

囲まれているモノ

(apple orange cake )

apple , orange , cake はそれぞれ、このリストの要素

要素は空白やタブ、改行で区切られる

(apple orange cake )

( apple
orange cake )

は同じリスト

要素は左から数える

(apple orange cake )

1番目の要素 apple
2番目の要素 orange
3番目の要素 cake

要素はリストであってもよい

(apple (orange cake) banana )

1番目の要素 シンボル apple
2番目の要素 リスト (orange cake)
3番目の要素 シンボル banana

要素はリストであってもよい

( apple ((orange) (cake)) 512 )

1番目の要素 シンボル apple
2番目の要素 リスト ((orange) (cake))
3番目の要素 数 512

リストの長さとは 要素の数

( apple orange cake )

リストの長さ 3

リストの長さとは 要素の数

( apple ((orange) (cake)) 512 )

リストの長さ 3
4ではない

基本データ

アトム, リスト

これだけ

データを評価する

計算するといってもよい

アトムの評価

数の評価

数はその数自身が価

数の評価

gosh> 1
1
gosh> 3.13
3.13
gosh> -1/3
-1/3

シンボルの評価

シンボルを評価すると 普通はエラー
gosh> apple
*** ERROR: unbound variable: apple

シンボルの評価

gosh> apple
*** ERROR: unbound variable: apple
エラー: アンバウンド バリアブル: apple

アンバウンド: バインドされていない
バリアブル: 変数

バインドされていない変数を評価するとエラー

シンボルの評価

評価してもエラーにならないシンボルもある
gosh> +
#<subr (+ :rest args)>

+には 足し算を計算する手続き(subr サブルーチン)が バインドされている

リストの評価

gosh> (+ 1 2)
3

1+2を計算した値 は 3

リストの評価

1と2を足した結果に3を足した結果を求めよ 算数ではこう書く (1 + 2) + 3

リストの評価

何と何を足すかを明確にするためにはカッコがあった方が良いよね

1と2を足した結果に3を足した結果を求めよ

忠実に書くなら、

算数なら
((1 + 2) + 3)

Schemeでは
(+ (+ 1 2) 3)

リストの評価

何と何を足すかを明確にするためにはカッコがあった方が良いよね

1に 2と3を足した結果を足した結果を求めよ なら

忠実に書くなら、

算数なら
(1 + (2 + 3))

Schemeでは
(+ 1 (+ 2 3))

演算子、被演算子

普通の算数の足し算

(1 + (2 + 3))

ここで、+ は演算子(オペレーター)と呼ばれる
1や2や3は演算の対象のデータで被演算子(オぺランド)と呼ばれる

被演算子が2つ必要な演算は2項演算という
被演算子が1つ必要な演算は単項演算という
被演算子が0個の演算は無項演算という
( 1より大きいn個の被演算子が必要な演算はn項演算という 
 あと被演算子の個数のことは アリティとも呼ばれる、2項演算ならアリティは2)

で、被演算子の間に演算子を置くのが、普通の算数の記法で中置記法

Scheme では (+ 1 (+ 2 3)) で演算子を 最初に書く 前置記法
ポーランド人の論理学者ウカシェヴィチが考案したとされていて
前置記法はポーランド記法とも呼ばれる。演算子を最後に書くのは 後置記法
逆ポーランド記法ともいう(プログラミング言語Forthとかでググってみよ)

リストの評価つづき

関数適用も リストで表す

xが1の時の 関数 f(x) の 値を求めることを
リストを使って (f 1) と表す
f(x)は 1引数の関数だけれど 2引数の関数 g(x,y) でも xに1, yに2 を入れて関数の値を求めることを
リストを使って (g 1 2) と表す

つまり(つづく)

リストの評価


先頭の要素 演算子 や 関数である
2番目以降の要素が、被演算子であり
引数(ひきすう)と呼ぶ

重要

通常引数をすべて評価してから、
先頭の要素(演算子,関数)へ引き渡す

引数

いんすう
ひきすう
ちなみに'ひきすう'は湯桶読み(ゆとうよみ)
ITギョーカイで まちがって読むと はずかしい
'いんすう' は 因数のほう

リストを評価する(計算する)

(+ 1 (+ 2 3))

これは3要素のリスト (長さ3のリスト)、評価する。

先頭要素の+が演算子
2番目の要素 1 , 3番目の要素 (+ 2 3) が被演算子
まず、先頭以外の要素を、それぞれ評価する
1を評価して1
(+ 2 3)を評価して5 
 もちろんこれも3要素のリストで
 先頭の要素 + が演算子,
 2番目の要素 2, 3番目の要素 3が被演算子 
 それぞれ評価して 2 ,3 を得て 2と3を足して5
(+ 1 5)

が評価されて 6が (+ 1 (+ 2 3))  の値

リストの評価(計算)

hoge が 1つ引数をとって2倍にして返す関数
  hoge(x) = x * 2  :  もちろんこれは scheme の式ではない
fuga が 2つ引数をとって最初の引数の値から2番目の値を引いて返す関数
  fuga(x,y) = x - y : もちろんこれも scheme の式ではない

だったら

(hoge 3) は 6を返す
(fuga 4 3)は 1を返す

(hoge (hoge 3)) は 12を返す

(hoge (fuga 4 3))は 2を返す

(fuga (hoge 2) 5) は -1を返す

関数の定義

hoge が 1つ引数をとって2倍にして返す関数
  hoge(x) = x * 2   : もちろんこれも scheme の式ではない

fuga が 2つ引数をとって最初の引数の値から2番目の値を引いて返す関数
  fuga(x,y) = x - y : もちろんこれも scheme の式ではない

schemeでは 関数の定義は スペシャルフォーム define , lambda を使う
(define hoge (lambda (x) (* x 2))) と書く
(define fuga (lambda (x y) (- x y)))と書く
これで
(hoge (hoge 3))は 12を返す
(hoge (fuga 4 3))は 2を返す
(fuga (hoge 2) 5)は -1を返す

関数の定義

実は lambda が関数(手続き)を作る特別な手続きなので
引数を2倍にして返す手続き
(lambda (x) (* x 2)) を使えば
((lambda (x) (* x 2)) ((lambda (x) (* x 2)) 3))
は 12を返す

さらにdefine が シンボルに値を バインドする特別な手続きで
(define hoge (lambda (x) (* x 2))) とすることで
((lambda (x) (* x 2)) ((lambda (x) (* x 2)) 3))(hoge (hoge 3)) と書ける

リストを評価する

先頭要素が 演算子あるいは関数あるいは手続き
残りは 被演算子あるいは引数
残りは すべて評価される

絶対に忘れないで

リストを評価する

先頭要素は 演算子(関数,手続き)
残りは 被演算子(引数)
引数は 演算子(関数,手続き)に渡される前に 全て評価される
(+ (* (- 5 4) (- 3 1)) 10)
演算子 +
1つ目の引数 (* (- 5 4) (- 3 1)) 
2つ目の引数 10
1つ目の引数 (* (- 5 4) (- 3 1)) を評価
(* (- 5 4) (- 3 1))
演算子 *
1つ目の引数 (- 5 4)
2つ目の引数 (- 3 1)
1つ目の引数 (- 5 4) を評価
(- 5 4)
演算子 -
1つ目の引数 5 これは評価すると値は5
2つ目の引数 4 これは評価すると値は4
- に 5 4 が渡されて 1が計算されて返る
同様に (- 3 1) を評価 (- 3 1)
演算子 -
1つ目の引数 3 これは評価すると値は3
2つ目の引数 1 これは評価すると値は1
- に 3 1 が渡されて 2が計算されて返る
1つ目の引数 (* (- 5 4) (- 3 1)) は
(* 1 2)
演算子 *
1つ目の引数 1
2つ目の引数 2
* に 1 2 が渡されて 2が計算されて返る
(+ (* (- 5 4) (- 3 1)) 10)
= (+ (* 1 2) 10)
= (+ 2 10)
= 12
  • もどる
  • 一覧にもどる