見出し画像

関数型プログラミング事始め (3) 変数の苦難

関数型プログラミングがはじめての方へ贈る入門の書
前節:効能 次節:配列の苦難
参考書:
・五味 弘「はじめてのLisp関数型プログラミング」技術評論社(2016)
・大山口 通夫、五味 弘「プログラミング言語論」コロナ社(2008)
・五味 弘「関数型プログラミングと数学(ITと数学)」技術評論社(2021)


関数型プログラミングの難しいところを紹介します。いいものを得るには苦難が伴います。はじめは面倒で難しいものと思うかもしれません。しかしその苦難の道は、手続き型やオブジェクト指向などの他のプログラミングパラダイムでも役に立つ道に続いています。副作用のないプログラムはどの言語でもどのシステムでも役に立つものです。

1.3 関数型プログラミングの苦難=その原因

前節では関数プログラミングの効能を紹介しました。しかしその関数型プログラミングは難しいと言われています。数学者みたいな感じの人が白衣を着て、プログラミングすると思われています(もちろん一部の人だけです)。

もちろん、そんなことはありませんが、それでも関数型プログラミングは難しいところがあります。ここでは難しいところ、苦難の道を紹介していきます。

(1) 変数は使えない? - 破壊的代入の禁止

関数型プログラミングは副作用(*1)を許しません。この副作用の原因のひとつが変数です。しかしすべての変数が悪いのではなく、破壊的代入(*2)を伴う変数が駄目なのです。
(*1) 関数型プログラミング事始め (1) 定義 参照
(*2) 変数に格納されている値を変える代入、既存の値がなくなる代入

例. 「関数型プログラミング事始め (1) 定義」の1.1の例(再掲)
int publicVariable = 0;
int fun(int x){
  publicVariable = publicVariable + x;
  return publicVariable;
}
この「publicVariable = publicVariable + x;」が変数に破壊的代入をしています。これが副作用の原因になります。

関数型プログラミングでは「変数が使えない」という噂があります。これは間違いで、正しくは「破壊的代入をする変数が使えない」ということになります。逆に言えば、値を変更しない変数は使えます。例えば、一時的に値を格納する変数は使えます。

グローバル変数については関数型プログラミング以外でも、使用は推奨されていません。グローバル変数は破壊的代入を行うために使われるので、副作用が生じます。だから、グローバル変数は使わないようにしましょう。

なおローカル変数でも同様の副作用は生じますが、その影響範囲はローカル変数の有効範囲内だけです。
# ローカル変数なら少しだけ使ってもいいです(現実主義者)。いや駄目だ(原理主義者)。

(考察)オブジェクト指向プログラミングの欠点「グローバル変数がいっぱい」

オブジェクト指向プログラミングでは、普通にプログラムを作ってしまうとグローバル変数がいっぱいになります。手続き型プログラミングよりも多いくらいです。

例えば、Javaのフィールド変数(メンバ変数、インスタンス変数)はメソッド関数におけるグローバル変数です。Javaプログラムではこのフィールド変数をいっぱい使いがちです。

なおフィールド変数よりも質の悪いのが、スタティック変数(クラス変数)です。この変数は極悪非道で、クラス内だけでなく、複数のクラスにまたがって悪影響を及ぼす悪者の変数です。

(弁解)グローバル変数を使いたい

このようなグローバル変数をなぜ使うのでしょうか。それは便利だからです。一瞬で状態を変えることができます。これがあまりにも便利です。だから使うのです。

でも使い過ぎに注意してください。1個のプログラムにグローバル変数は1個までです。それ以上多いと健康を害します。

(対策)グローバル変数は引数に繰り込み

破壊的代入を伴う変数が使えないですが、それを引数に繰り込めば大丈夫です。「関数型プログラミング事始め (1) 定義」の1.1の例であれば、以下のようになります。

例.
int fun(int x, publicVariable){
  return publicVariable + x;
}

(次回予告) (2) 配列の苦難

次回は今回の関数型プログラミングの難しさの続きになり、配列が使えない?をお送ります。変数が使えないに続いて配列ですが、これは今回と同じ原因の破壊的代入がキーになります。続きは次回で。

参考:プログラミング言語はどれがお得?(前編)|五味弘 (note.com)
参考:プログラミング言語はどれがお得?(後編)|五味弘 (note.com)


よろしければサポートをお願いします!