関数作成についてちょっと言っておくことがある!

いや、まじでさ・・・関数作成する上で個人的に気をつけていることなんだけどね?
みんな気をつけていると思っていたよ?
ちょっと微妙にケンカ腰だけど気にせずドーゾ。

副作用ってナニ?とか言うな!

副作用、つまりサイドエフェクトっつーのは、プログラム言語の関数が、与えられた引数から結果を出力するまでのあいだに状態を変えちゃうこと。
そもそも、数学の関数とプログラム言語の関数は(本質的にと言っていいのかどうかまでは知らんが)違うものであり、一番泥臭い感じのするところであるのだよ。
数学の関数は、引数として同じ物を入れた場合に、100%同じものを出力するのに対して、プログラム言語の関数は引数が同じであっても状態によって出力が違う場合がある。

int status = 0;

int hoge(int hikisu)
{
    status++;

    return (hikisu+status);
}


void main(void)
{
    printf( "%d\n", hoge(2));
    printf( "%d\n", hoge(2));
    printf( "%d\n", hoge(2));
}
    

要するにこういうことだ。
hoge関数はstatusという状態を変えるという副作用があることになる。

副作用かよ!ばかー

ナニがダメなのかというと、副作用があると、とたんにプログラムが麺になってしまう事。
読む人は思うわけだ、この変数はどこまで影響するのかと。

個人的意見ですけど副作用があると下のような感じ。

  1. プログラムの可読性が減る。
  2. プログラムのバグが増える。
  3. バグが出たときに理由がわからなくなるときがある。
  4. マルチスレッドだと思わぬアクシデント。
  5. 部品化がしにくくなる。
  6. よって再利用しにくい。

理由はさまざまですけど、基本的には想定外の状態の組み合わせが引き起こすバグとか。
つまり、現在のプログラムではこれだけの状態しかありえないからきれいに動くけど、ソース改変や他のシステムに適用した場合の状態まで設計していないパターンが一番怖いわけ。

まとめ

広域変数やめるしかあるまい。
もしくは広域変数にしっかりコメントして、再利用なんてあきらめる。
あと、広域変数は広域変数だとすぐわかる命名規則をつくれ。
C++なら最低限クラス内部で閉じ込めろ、閉じ込められないなら設計を見直せ。

副作用好きは「綾織」という副作用型言語があるのでそっちへ。