Page 1
純粋 vs 副作用
PHPはなぜ難しいのか?
Pure vs. Side Effects: Navigating PHP's Complexities
pixiv Inc.
USAMI Kenta
2025-06-28 #phpcon
PHPConference Japan 2025
公開日:
by USAMI Kenta@tadsan
に東京都大田区蒲田の大田区産業プラザ PiOで開催された『PHPカンファレンス2025』でレギュラートーク(25分)として発表しました。
純粋 vs 副作用
PHPはなぜ難しいのか?
Pure vs. Side Effects: Navigating PHP's Complexities
pixiv Inc.
USAMI Kenta
2025-06-28 #phpcon
PHPConference Japan 2025
お前誰よ
今回のお題
純粋関数 pure function
副作用 side effect
きいたことありますか?
数学的な関数?
f(x) sin(x)
関数fのxに2を代入する
f(x) =2x
f(2) =4
関数fのxに2を代入する
2に関数fを適用する
f(x) =2x
f(2) =4
f(x) =2x
f(x) f(0) f(1) f(2) f(3)
2x 0 2 4 6
f(x) f(0) f(1) f(2) f(3)
2x 0 2 4 6
いつどこで計算しても結果は同じ!
数学的な関数
f(x) sin(x)
プログラミングに
おける関数
今日は特に区別しません!
f(x) =2x
$f = function($x) { return 2 * $x;
};
f(x) =2x
$f = fn($x) => 2 * $x;
0〜3までの数に $f 関数を適用する
f(x) =2x
f(x) f(0) f(1) f(2) f(3)
2x 0 2 4 6
0〜3までの数に $f 関数を適用する
$f = fn($x) => 2 * $x;
array_map($f, );
[0, 1, 2, 3]
f(x) f(0) f(1) f(2) f(3)
2x 0 2 4 6
PHP関数
=
数学の関数
PHP関数
≠
数学の関数
関数の結果を画面に表示する
$f = fn($x) => 2 * $x;
echo "f(2) = ", $f(2);
echo "sin(0) = ", sin(0);
関数の結果を画面に表示する
われわれは
var_dump() も 関数と呼んでいる
$f = fn($x) => 2 * $x;
var_dump(["f(2)" => $f(2)]);
var_dump(["sin(0)" => sin(0));
関数の結果を画面に表示… しない
計算した結果を
どこにも使わない
$f = fn($x) => 2 * $x;
$f(2);
計算資源の無駄!
sin(0);
SDGsに反する!
なぜ同じような関数なのに違いが…
関数はひとつ!じゃない!!
画面に文字を表示する
printf("Hello, world!");
文字列を生成して
sprintf("Hello, world!");
捨てている!
画面に文字を表示する
(or HTTP出力)
作った文字列は
受け取らないと意味ない
なぜ差がついたのか…
慢心・環境の違い
状況を整理しましょう
PHPの「関数」には種類がある
PHPの「関数」には種類がある
何かってなんだよ…
休 憩
話は変わって
ユニットテストは
好きですか?
好きですか?
好きかはともかく
お得なことはいっぱい
ユニットテストの基本スタイル
テスト対象の関数
function twice(int $n): int {
return $n * 2;
}
ユニットテストの基本スタイル
function twice(int $n): int {
期待値と結果を
return $n * 2;
比較してチェック
}
class TwiceFuncTest extends TestCase {
function test(): void {
$this->assertEquals(4, twice(2));
}
}
ね、簡単でしょ?
簡単に済まないのが
現実
純粋 vs 副作用
PHPはなぜ難しいのか?
Pure vs. Side Effects: Navigating PHP's Complexities
pixiv Inc.
USAMI Kenta
2025-06-28 #phpcon
PHPConference Japan 2025
PHPの「関数」には種類がある
何かってなんだよ…
いつの間にか
どこかの何かに
影響を及ぼす
あるいは勝手に どこかの何かの
影響を受ける
何かってなんだよ…
PHPの「関数」には罠がいっぱい!
罠 = 副作用
「テストしにくい」の正体
不規則に副作用を
起こすコードは
容易に制御不能になる
秩序のないコードが
人間に牙を剥く
休 閑 題 話
ドラえもん
ご存じですか?
侵略者が送り込んだ未知の技術
の電子頭脳に対して…
工学的アプローチによって 戦力化を提案する野比のび太
『大長編ドラえもん(7) のび太と鉄人兵団』
著: 藤子・F・不二雄/藤子プロ
1987年2月25日初版第1刷、2011年第86刷
Kindle版 p97, p102より引用
みたことのある回路に なおしゃいいんだよ!
のび太は
技術者の鑑
制御できないものは
制御できる部分に
ブレークダウンする
ヘキサゴナルアーキテクチャ(Hexagonal architecture翻訳)
Alistair Cockburn著、tai2訳
2015年10月9日公開、2025年6月28日閲覧より引用
クリーンアーキテクチャ(The Clean Architecture翻訳)
Robert Martin著、tai2訳
2015年10月9日公開、2025年6月28日閲覧より引用
副作用がある部分を切り離す
制御できないものは
制御できる部分に
ブレークダウンする
「なんたらアーキテクチャ」は
構造をわかりやすく 図示してくれるが、
必須ではない
プログラム上で
制御しやすい基本単位
#とは
そうです
純粋関数
純粋関数とは…
純粋の反対語は不純(impure)
基本的に…
こんな関数は純粋じゃない!
関数の結果を画面に表示… されない
計算した結果を
どこにも使わない
$f = fn($x) => 2 * $x;
$f(2);
計算資源の無駄!
sin(0);
SDGsに反する!
やるじゃん
全関数を純粋と不純に分けたい…
PHPStanの純粋判定を支える仕組み
PHPDoc @pure タグ
resources/functionMetadata.php
JetBrains/phpstorm-stubs
「不純な純粋」というTig-HugなOxymoron
純粋じゃなくても
戻り値が大事な
関数はある
/リソースは
CurlHandler
外部から観測できない 内部状態に依存するので
純粋と言いがたい
PHP 8.5に導入される新機能
#[NoDiscard]
関数の結果を画面に表示… されない
計算した結果を
どこにも使わない
$f = fn($x) => 2 * $x;
$f(2);
無計駄算な資の源での除無去駄す!る
sin(0);
SDGs最に適反化する!
ではこれを実装すれば
うまくいくのか?
そう上手くいかない…
これは両方純粋なので
警告されるべき
純粋な呼び出しなので
警告されるべきではない
原因はわかっていて 書きかけのPRがある
_人人人人人人人人人_ > 僕の怠惰が原因 <  ̄Y^Y^Y^Y^Y^Y^Y ̄
正直、体調不良と 若干の燃えつきが
重なっていた
PHPStanを
理解している人は
限られている
ガチでPHPStanを 極めてみたい仲間を
増やしたい!!!
phpusers-ja Slack
