無名関数

出典: フリー百科事典『ウィキペディア(Wikipedia)』
移動先: 案内検索

無名関数英語: anonymous functionあるいはnameless function[1]とは、名前付けされずに定義された関数のことである。無名関数を表現するための方法には様々なものがあるが、近年[いつ?]主流となっているのはラムダ式による記法である。無名関数を表現するリテラル式は、関数リテラル (function literal) とも呼ばれる。値がある場合は関数オブジェクトであるものが多い。

ラムダ式[編集]

ラムダ式 (lambda expression) はラムダ計算と関係が深く、関数型言語で特によく採用されている。

Haskellにおける例を示す。

let add = \x y -> x + y -- 2つの引数を取ってその和を返す無名関数を定義し、変数addにバインドする。
print $ add 2 3

関数型ではない言語においても、ラムダ式を言語機能として取り入れる動きが活発である。

C#ではC# 3.0にて導入された。以下に例を示す。

Func<int, int, int> add = (x, y) => x + y;
Console.WriteLine(add(2, 3));

C++ではC++11にて導入された。以下に例を示す。

auto add = [](int x, int y) { return x + y; };
std::cout << add(2, 3) << std::endl;

JavaではJava 8にて導入された。以下に例を示す。

import java.util.function.*;
...
BiFunction<Integer, Integer, Integer> add = (x, y) -> x + y;
System.out.println(add.apply(2, 3));

匿名メソッド[編集]

C# 2.0では匿名メソッド (anonymous method) が導入された[2]

Func<int, int, int> add = delegate(int x, int y) { return x + y; };
Console.WriteLine(add(2, 3));

C# 3.0以降では前述のようにラムダ式も導入されている。通例、ラムダ式のほうが簡潔であり、またラムダ式は式木として扱うこともできるため、基本的にC# 3.0以降ではラムダ式を用いる。ただし、匿名メソッドではパラメーターリストを省略できるので、匿名メソッドはさまざまなシグネチャを持つデリゲートに変換できるが、ラムダ式ではそれができない。この点において匿名メソッドはラムダ式に勝っている。

JavaScriptの無名関数[編集]

JavaScriptではfunctionというキーワード(予約語)を用いて記述する。

var add = function(a, b){ return a + b; }; // 2つの引数を取ってその和を返す無名関数を定義し、変数addにバインドする。
alert(add(2, 3));

Luaの無名関数[編集]

Luaにおける関数は第一級オブジェクトであり、すべての関数が本質的に無名関数である。名前付きの関数とは、関数オブジェクトへの参照を保持する変数にすぎない。

function add(x, y) return x + y end

というコードは、次のコードに対する糖衣構文である。

add = function(x, y) return x + y end

Pythonの無名関数[編集]

Pythonではlambdaというキーワードを使う。Python特有の注意点として、lambdaの内容には式のみが書け、文は書けない点が挙げられる。

add = lambda a, b: a + b # 2つの引数を取ってその和を返す無名関数を定義し、変数addにバインドする。
print(add(2, 3))

無名関数の特徴[編集]

  • 名前で参照できないため、再帰のためには何らかのテクニックがほぼ必要になる(無名再帰を参照)。

メリット[編集]

  • 一度しか使わない関数の名前を付けなくて済む。名前の衝突を考えなくて済む。
  • 関数の引数などに直接渡せる。

特にC++ではアルゴリズム関数テンプレートにおける述語 (predicate) としての関数オブジェクトの明示的な定義が不要になり、簡潔なコードを記述しやすくなる。

C++14での例を示す。

#include <iostream>
#include <algorithm>
#include <vector>

int main() {
  const std::vector<int> ary { 1, 5, -1, 3, 0, -2, };
  std::cout << "Count of negative numbers = " << std::count_if(ary.begin(), ary.end(), [](auto x) { return x < 0; }) << std::endl;
  return 0;
}

脚注[編集]

  1. ^ 「anonymous」は「匿名の」という意味も持つため、「anonymous function」は日本語で「匿名関数」と訳されることも多いが、「匿名」は(本当の)名前を匿(かく)すことを意味する。anonymous functionの「anonymous」は「名前がない」ということを意味しているので、ニュアンス的には「無名関数」のほうが適切な訳である。
  2. ^ MSDN日本語版ドキュメントでは「匿名メソッド」としているので、この節はそれに従った。匿名メソッド (C# プログラミング ガイド) | Microsoft Docs

参考文献[編集]