入力 → 函数 → 出力
1と2 → 足し算 → 3
上に函数の抽象的な概念,下に函数の実例を示した. "足し算"という名の函数は,2つ以上の入力を数学的に足しあわせ,その結果を出力として返している. これは下の様にも書ける.
f(1,2) → 3
ここでf( )という函数は"足し算"である. こちらの記法の方がより簡潔である. 函数に引数を複数渡す場合は,引数をカンマ(,)で区切ることとした. 函数"足し算"に1と2を引数として渡すと,その結果である3が返答として返される. つまり,f(1,2)は3という数値として扱える. 同様に,f(6,2)ならば,8という数値と同等の意味を持つと考えてなんら問題無いわけである. この考え方を数学に持ち込めば,下の計算2つは表記は違えどまったく同じ意味となる.
1 + 2 + 4
f( f(1, 2), 4)
上は説明するまでもなく,数学の規則により左から順番に加算してゆけば結果を得られる. つまり,まず1+2が行われ,その結果の3と+で結ばれた4が足し合わされた答え7が結果として返されるわけだ. 下でも同じことが起こっている. より入り子になった函数を優先して実行してゆけば良い. つまり,まずf(1,2)が評価される. これは数値3と同じ意味を持っていることは先に述べた通りである. つまり外側の括弧(函数)である,f(f(1,2),4)はf(3,4)を評価することと何ら違いは無いわけである. よってこの結果は7であるから,f(f(1,2),4)は数値7とまったく同じ意味を持つ函数の組み合わせであると言える.
新しい函数をつくってみよう. ここがパズルゲームとプログラミングの違いである. パズルゲームは最初に与えられたピースのみを使ってゲームを解くものだが,プログラミングは必要ならばピースを自分でつくることが出来るのだ. では,新たなピースをつくろう. ある数字を2乗する函数をつくる. 下にそれを示す.
g(n) = (n * n)
これはnを引数とした函数である. 函数の中身(構造)はイコール(=)で結んだ先に示すこととした. nのところに任意の数値を入れてやると,上のnの部分がすべてその任意の数値となり,計算された結果が返されるのだ. 例えば下のように,
g(3) = (3 * 3)
上の函数がどの数値と等しい意味を持つかは分るだろうか. それは9である. 3*3を計算した結果と等しい意味を持つ函数. 同様に,g(5)は25という数値と同一視して構わず,g(1.5)ならば1.5*1.5,つまり2.25と同じものとして扱えるわけである.
では,函数f( )とg( )なる2つのピースを組み合わせてみよう.
f( g(3), g(4))
この函数の組み合わせを,25として見れるようになれば,この概念を習得したものと言える. 25に見えなくても,次のように順序よく函数を評価してゆけば良い. まず,一番入り子になった函数から先に評価してゆく. g(3)とg(4)である. 両方とも引数を2乗した数値を返す函数であった. よって,g(3)は3*3と同じであり9とも同じである. g(4)も同様に,4*4と同じであり16と同じものとして見ることができる. するとf( )の中身は次のように見ても良いこととなる.
f(9, 16)
f( )は2つ以上の引数を足し合わせた結果と同じ意味を持つ函数であった. つまり,9+16と同じこととなるから,25という数値とf(g(3),g(4))はまったく同じものとして見ることが出来るのだ. 表記はまったく違っても,意味は同じ. この考え方がプログラミングには大切であると考える. ちなみに,上に説明した計算は"345三角形"の斜辺の長さの2乗をピタゴラスの定理により求めたものである. "345三角形"とは,隣辺の長さが3と4,斜辺の長さが5の直角三角形である. そしてピタゴラスの定理は,直角三角形の各辺の長さの関係を示したものである. 斜辺(c)の長さの2乗は,他の隣辺(a,b)長さの2乗の和に等しい,という定理である.
a^2 + b^2 = c^2では,2つの隣辺の長さ(a,b)が与えられたら,その直角三角形の斜辺の長さの2乗(c^2)を求める函数をつくってみよう. なにも難しく考えることはなく,下のように簡単である.
h(a, b) = f( g(a), g(b))
函数hは,隣辺の長さを2つ引数としてとると,その直角三角形の斜辺の長さの2乗を返す. 使い方は次のとおりである. 例えば"345三角形"ならば,
h(3, 4)
これは25と同じ意味をもち,隣辺が3と4の直角三角形の斜辺の長さの2乗と同じ意味ももつ. そのわけは,
h(3, 4) → f( g(3), g(4)) → f(9, 16) → 25
と評価出来るからである. 詳しくはすでにf(g(3),g(4))の説明で述べた通りだ.
さて,ここまで出来ると少し欲が出る. 折角ならば,斜辺の2乗の長さでは無く,斜辺の長さが欲しくなる. それならば,もうひとつピースをつくって,今までのピースと組み合わせてゆこう.
i(n) = (√n)
この函数i( )は,引数を1つ取り,その数値の平方根を結果として返す. 例えば,i(4)は2に等しく,i(2)は1.4142…すなわち2の平方根に等しい,といった具合である. この新たなピースを組み合わせれば,直角三角形の斜辺の長さを求めるプログラムをつくれたこととなる. つまり,
j(a, b) = i( h(a, b))
もしくは,
j(a, b) = i( f( g(a), g(b)))
である. この函数j( )こそ,2つの隣辺の長さを引数として与えると,その直角三角形の斜辺の長さを返してくれる函数である. 例の如く"345三角形"だと次の様になる.
j(3, 4)
これは,斜辺の長さである5と同じ意味を持つ. j( )という函数がどんな仕組みをしているか,どんな函数の組み合わせで構成されているかなどを考える必要は無く,ただj( )という函数は斜辺の長さを意味しているものとだけ分かれば使えるのである. これはプログラミングをする上でとても都合が良いということに気づけるだろう. これがプログラミングの一である,"函数型プログラミング"と呼ばれる手法のメリットである. このメリットは,小さく単純な函数,すなわちピースを組み合わせて行き,あるひとつの複雑な計算をとても簡単な形として表現することにある. j(3,4)の中身はi(f(g(3),g(4)))である,と言われてもその意味は理解しづらく納得し難いが, j(3,4)は隣辺が3と4の直角三角形の斜辺の長さである,と言われれば納得できるし理解もしやすいことだろう. 特に,大きなプログラムを書く時は,この手法が自分の頭のなかの設計図をよりシンプルものとしてくれる.
7324922001126193681
https://www.storange.jp/2013/07/programming.html
https://www.storange.jp/2013/07/programming.html
Programming
2013-07-18T21:02:00+09:00
https://www.storange.jp/2013/07/programming.html
Hideyuki Tabata
Hideyuki Tabata
200
200
72
72