今日は前回に引き続きお友達のWEBデザイナーさんからの依頼で、プログラミングにおける「関数」とは何ぞやという話をしてくれということで書いてみます。

高卒以上のレベルの人でプログラム言語に慣れ親しんでない人が「関数」と聞くと、数学で習った「二次関数」とかの「関数」を思い出すと思います。
※「高卒レベルの人」でと誤解される書き方をしていました。申し訳ありません。正しくは上記の通り「高卒以上のレベルの人」です。

数学で習った「関数」は、ちょっと意味は似ているところがありますが、この際きれいさっぱり忘れたほうがいいです。ということで数学の関数は忘れて話をすすめます。

で、関数っていうのはプログラミング言語やプログラマーによって結構考え方や概念が異なりますので、BASIC(VBではない)やPerlで育ってきた僕の個人的な考えで書いていきます。

お友達デザイナーがActionScriptを勉強していて躓いたらしいですので、僕はASが書けないってことでJSで書いていきます。



まず、簡単なお話から。

Javascriptの入門向け命令辞典を読んでいて、たとえば、「特定の文字列をURLエンコードしたい」というときは以下のような命令を書けと書いてあることがあります。

var str = '文字列';
str = encodeURIComponent(str);
document.write( str );

これを実行すると、「%E6%96%87%E5%AD%97%E5%88%97」と表示されると思います。

encodeURIComponent()という命令を使うことで、「文字列」という文字列を簡単にURLエンコードできます。

実はこの「encodeURIComponent()」が「関数」です。



関数とは、ざっくりと簡単に言えば、決まった手順を一まとめにしておいて、再利用できるようにしたものです。

Javascriptの入門書などで「関数」と言えば、上記のような説明をした上で、

function 関数名( 引数1, 引数2... ){
    手順;
    return 返り値;
}

と書け。みたいなことが書いてあります。

まったくもって、間違いじゃないんですけど、その前に、自分で作らなくても、

Javascriptには最初から前述「encodeURIComponent()」のような便利な関数はたくさん用意されているんです。

たとえば他に
document.write()
alert()
confirm()
window.close()
などなどあります。

こうやって書いてみると、どうでしょうか?プログラミングの初心者でも、これまで書いたプログラムのコードの何割かは関数を使っている部分で埋められているのではないでしょうか?関数は現在の発展したプログラミングにおいては、とても有用なもので、プログラミング言語によって最初からたくさんの関数が用意されています。

前述の「function」を使った「自分で作る関数」は、最初から用意されている関数のほかに、決まった命令をまとめておいたり、それを再利用したりしたい時に作る関数で、一般的に「ユーザー定義関数」などと呼ばれます。言語が最初から用意している関数に対して、自分で作る関数だから「ユーザー定義関数」。分かりやすいネーミングです。はい。

※完全な低級言語やC言語のような低級に近い言語は関数は少なくなるかも。
※window.close()などはオブジェクトのメソッドなので厳密には「最初から用意された関数」ではない。
↑ここの※部分はお友達デザイナは無視したほうがいいですwwww


まず、関数の使いどころです。ここからは入門書を片手に読んでください。

前述の通り、関数は決まった手順をまとめておくもの、そしてそれを再利用できるようにしたものです。

料理で言うと、ダシとかスープみたいなものかな。前もって「一番ダシ」とか用意しておくことがあると思います。関数は、それに近いかな。

「引数」は、そこに醤油や塩などの追加調味料や、メインとなる食材など、目的とする料理に合わせて何かを追加してひとつの料理として完成させたり、また違うひとつの材料にしていったりして行くわけですね。材料を入れたりして加工したものが「返り値」に近いですかね。

では実例。まず関数を使わない例です。

例1

var str_1 = 250;
str_1 = Math.floor( str_1 * 1.05 );
alert( str_1 + '円です。' );

var str_2 = 500;
str_2 = Math.floor( str_2 * 1.05 );
alert( str_2 + '円です。' );

端数切捨てで消費税額を計算して、その結果をalert()するという内容ですね。

上記例の場合、2つの額に対して消費税計算をしていて、同じような処理を繰り返しています。
この場合同じパターンが2つですから、まだマシですけど、3つ4つ・・・となっていくとなんだかなぁとなります。

こういった決まったパターンがあるときに使うのが関数というわけですね。



では、実際に関数を使って書き直してみましょう。

関数を使うといっても、プログラム全体の設計によっていくつかの関数の実装が考えられます。
例1においてもそうです。



関数実装例パターン1

例1のプログラムを見て重複している部分は、
・変数に1.05をかける。
・1.05をかけた変数を小数点以下切り捨てる。
・この変数のあとに「円です」をつけてalert
という流れです。

ここを関数にします。

例2

//↓ここで関数定義!
function taxAndAlert( str ){
str = Math.floor( str * 1.05 );
alert( str + '円です。' );
}


//↓ここから実行文
var str_1 = 250;
taxAndAlert( str_1 );

var str_2 = 500;
taxAndAlert( str_2 );

こんな感じです。 例1と比べるとMath.floorなどの何回もあった面倒な手続き一式がまとめられています。ここが関数。実行文のところでは作った関数「taxAndAlert」を実行しているだけで、Math.floorを何度も書いたりなど面倒が少しラクになります。



関数には、手続きをまとめてラクにするだけではなくて、後々修正がラクになるという効果もあります。例1・2では消費税計算をしているわけですが、2009年8月現在では、そう遠くない未来に消費税率アップがされることが目に見えています。仮に消費税率が8%になったとすると、例1では「1.05」を「1.08」へ書き換える箇所が複数ありますが、例2ではそれが関数の中1箇所だけで済みます。これは大きなプログラムにとってはメンテ性の向上につながります。


関数実装例パターン2

さて、話は少し戻り、関数の実装パターンはいくつか考えられるということを書きました。次のパターンを考えてみましょう。

例3

//↓ここで関数定義!
function taxAndReturn( str ){
str = Math.floor( str * 1.05 );
return str;
}

//↓ここから実行文
var str_1 = 250;
alert( taxAndReturn( str_1 ) );

var str_2 = 500;
alert( taxAndReturn( str_2 ) );

↑ 例2と比べてみると、関数の中でalertを実行していないことが分かります。

ぱっと見、「あれ?繰り返しやっていることをなぜ関数にしないのだ」と思うかもしれません。確かに例1を関数で書き換えるのであれば、例2が最もいい例なのかもしれません。しかし、消費税計算というのは非常によく使う計算ではありますが、alertを使って表示するということはそれほど多くありません。

関数には返り値(かえりち)というものが用意されていて、返り値を使うことで、関数の中で計算させた結果を、元のプログラムに戻してやることができます。元のプログラムはその返り値を使って、好きなことができるわけですね。たとえば、返り値を積算していけば、合計値を計算することができたりします。返り値をうまくつかうことで、関数の機能をシンプルにして、関数の再利用性をあげることもできるのです。

このように関数は、すべてをひとつにまとめるのではなく、本当に繰り返しが多く、まとめるべき手続きをまとめるのも、関数の利用価値を高めるポイントです。


関数実装パターン3

でも、やっぱりこの際、alertも関数でやっちゃいたいよ!と思うこともありますよね。
次の例はどうでしょうか。

例4

//↓ここで関数定義!
function taxAndReturn( str ){
str = Math.floor( str * 1.05 );
return str;
}
function taxAndAlert( str ){
alert( taxAndReturn( str ) );
}

//↓ここから実行文
var str_1 = 250;
taxAndAlert( str_1 );

var str_2 = 500;
taxAndAlert( str_2 );

例4では、関数を二つ作りました。関数の中から関数を呼び出しています。そう、消費税計算をする関数と、その関数を呼び出してalertする関数の二つを作ったわけです。こうすれば、消費税計算に限定することで利用価値をあげた関数の価値をそのままに、alertを呼び出すという手続きも再利用できるようになったわけです。



かなーりざっくりした話でしたが、以上が、関数の使いどころです。

・繰り返しを関数にすることで、プログラムの可読性があがる。何度も同じことを書かなくていい。
・繰り返しを関数にすることで、プログラムを後日改修するときにラクになる。

というところがポイントで、

・関数はプログラム全体を見渡して、関数の内容はシンプルに。
・関数をいくつかつくり、関数と関数を関連させていくことでさらに便利に。

ここが関数の運用・設計において重要な点です。

個人的には、関数は、プログラミングを嫌いにならないためのひとつの道具でもあると思います。何度も同じことして「うがぁっ!!!」みたいなストレスが一番人間にとってよくないと思うからです。関数。頑張って覚えましょう。