5.1 関数の本質
関数は、入力を受け取り、処理し、結果を返します。
入力 → 関数 → 出力
def add(a: int, b: int) -> int:
return a + b
関数を比較するときは、次を確認します。
引数の型
戻り値の型
デフォルト引数
可変長引数
名前付き引数
関数を値として扱えるか
外側の変数を捕捉できるか
副作用を持つか
5.2 第一級関数
関数を通常の値として扱える言語では、関数を変数へ代入したり、別の関数へ渡したりできます。
def double(value):
return value * 2
operation = double
result = operation(10)
関数を引数として渡せます。
numbers = [1, 2, 3]
result = map(double, numbers)
これを第一級関数と呼びます。
5.3 高階関数
関数を受け取る、または関数を返す関数です。
def apply_twice(function, value):
return function(function(value))
result = apply_twice(lambda x: x * 2, 3)
# 12
map、filter、reduceも高階関数です。
5.4 クロージャ
外側のスコープにある変数を保持する関数です。
def create_multiplier(factor):
def multiply(value):
return value * factor
return multiply
double = create_multiplier(2)
print(double(10))
multiplyは、create_multiplierの実行終了後もfactorを保持します。
クロージャは次の用途で使われます。
コールバック
イベント処理
状態のカプセル化
非同期処理
関数型処理
5.5 純粋関数と副作用
純粋関数には二つの性質があります。
同じ入力なら必ず同じ出力を返す
外部状態を変更しない
def add(a, b):
return a + b
副作用を持つ関数は、外部世界へ影響を与えます。
def save_user(user):
database.insert(user)
代表的な副作用は次です。
ファイルの読み書き
データベース更新
ネットワーク通信
画面出力
グローバル変数変更
現在時刻や乱数への依存
副作用は必要ですが、計算部分と分離するとテストしやすくなります。