読者です 読者をやめる 読者になる 読者になる

はむはむエンジニアぶろぐ

このブログのコンセプトは"ハッキングの為なら愛する家族を傷つけることをいとわない" 自分にとってエンジニアリングは "手段ではなく生きる目的" である

参照透過性とは何だ?

PHP 関数プログラミング

f:id:secret_hamuhamu:20150404170600p:plain
関数型プログラムでよく聞く言葉である参照透過性。
参照透過とはどういうことなのかPHPで実装してみた。

参照透過性とは?

参照透過性とは、次のような特徴がある。

  • 同じ関数であれば、いつ実行しても結果が同じであること。
    • 引数が同じなら戻り値は、必ず同じであるということです
  • 副作用がないこと
    • global変数の使用などによる状態の変化がないこと
    • ファイルのI/Oやデータベースも状態の変化に含まれてしまいますが、そこは局所化してなるべく切り分けましょう

このような関数は、参照透過性のある関数とはいえません

<?php
function addDay($addend)
{
    return date('Y/m/d', strtotime(sprintf('+%s day', $addend)));
}

addDay(1);

引数に数値を受け取り、現在の日付に+1をしていますが、実行する日が異なれば結果も異なります。
参照透過性の性質を持っていないことが分かりますし、この関数はテストしづらいことが分かります。

変更を加え 参照透過性のある関数にする

<?php
function addDay($day, $addend)
{
    return date('Y/m/d', strtotime(sprintf('%s +%s day', $day, $addend)));
}

addDay('2015/04/01', 1);

日付を引数として受け取る形にしました。
これにより、引数が同じであれば戻り値は、必ず同じになります。

参照透過性によって何が嬉しいのか?

  • テストがしやすい
  • 副作用が無いため、並列実行や遅延実行で使用しやすい

最近読んだ本

関数プログラミング 珠玉のアルゴリズムデザイン

関数プログラミング 珠玉のアルゴリズムデザイン

JavaScriptで学ぶ関数型プログラミング

JavaScriptで学ぶ関数型プログラミング