関数プログラミングにおける本当の「関数」の意味とは何か?

こんにちは、Jeannieです。

タイトルの通り、今回は関数プログラミングにおける本当の「関数」の意味について記事を書こうと思います。

関数プログラミングや関数型言語で最も特徴的な「関数」について、理解を深めていきましょう!

関数プログラミングにおける関数の考え方

関数プログラミングにおける「関数」の考え方は少し特殊です。

一般的なプログラミングで耳にする「関数」とはテイストが少し違うので、それぞれの違いを説明していきます!

一般的なプログラミングにおける関数

プログラミングをする時に一般的に使われる「関数」とは、

特定の命令を一つにまとめた処理ブロック

という意味で使われることがほとんどです。

Javaなどのプログラミング言語でいうところのメソッドですね。

public void sample() {
    // 標準出力に文字列を出力
    System.out.println("一般的な関数");
}

こんな感じで複数の処理をまとめたものが一般的に関数と呼ばれるものです。

関数プログラミングにおける関数

一方で、関数プログラミングにおける関数は、

与えられた入力の値のみから、出力となる値をただ1つ決める規則

という数学的な意味での関数になります。

上で書いた一般的な関数のコード例では、入力値(引数)も出力値(戻り値)もありませんので、関数プログラミングにおける関数の定義を満たしていません。

関数プログラミングの定義を満たす関数は、以下のような関数です。

public int sample(int num) {
    // 入力値(引数)を2倍にして返す
    return num * 2;
}

1.引数として数値型の値を受け取る(入力)
2.その値を2倍にして返す(出力)

上記コードにおける sample は与えられた数値のみから出力値を得ています。
いつ、どんな時に使っても与えられた数値が同じであれば同じ出力値が得られます。
これが数学的な意味での関数、つまり関数プログラミングにおける関数となります。

「副作用」を持つ処理の考え方

一般的な関数と関数プログラミングにおける関数の違いについて説明しましたが、「副作用」についても触れておこうと思います。

副作用をもつ処理も「関数プログラミングにおける関数」とは違う考え方なので、さらっと理解しておきましょう。

「副作用」とは?

副作用とは、

プログラミングにおいて、「状態」を参照したり、「状態」に変化を与えることで、次回以降の結果にまで影響を与える効果

のことです。
「ん?」となりそうですが、簡単にいうと変数への代入なんかが副作用です。

プログラムによっては変数の中身が書き換わっていくことはよくあることで、その変数を参照したときにその時点での中身が何であるは「状態」の一つです。
次回の参照時には、前回の中身とは違う「状態」が結果として得られる可能性があります。

関数プログラミングにおいて副作用をもつ処理は「関数」ではない

関数プログラミングにおける関数の定義は、「与えられた入力値のみから出力となる値をただ1つ決める規則」でした。

副作用をもつ処理は「状態」が変わってしまうので、与えられた入力値を使って実行した結果が毎回変わってしまう可能性があります。

そういう意味で副作用をもつ処理は、関数プログラミングにおける「関数」の意味には含まれません。

まとめ

今回は「一般的な関数」と「関数プログラミングにおける関数」の違いについて説明しました。

関数の種類関数の定義
一般的な関数特定の命令を一つにまとめた処理ブロック
関数プログラミングにおける関数与えられた入力の値のみから、出力となる値をただ1つ決める規則

これから関数プログラミングを学んでいく上では、「副作用のない数学的な意味での関数」という意味を把握することが重要です。

これからじっくりと1つ1つ理解していきましょう!

コメント