PHPのWalrus演算子

2019年10月にPython 3.8でWalrus演算子(:=) 経由 ペップ572 プログラミング言語の歴史上最大の論争の一つを引き起こした。この論争は非常に激しく、Pythonの発明者は グイド・ヴァン・ロッサム 2018年7月、釈放前にもかかわらず、BDFL(終身の慈悲深い独裁者)。2019 年の初めから、Python は選出された運営委員会によって統治されるようになりました。


if (n := len(items)) > 10:
    print(f"List is too long ({n} elements)")

ガバナンス上の亀裂は、Walrusに関する議論の直後に発生しました。これは、単一の言語機能が構造的な影響を及ぼした稀有なケースです。ヴァン・ロッサム氏は声明の中で、「決定打となったのは、非常に物議を醸したPython拡張提案でした。私がそれを承認した後、人々はTwitterなどのソーシャルメディアで、私を個人的に傷つけるような発言をしました」と述べています。

彼は続けた。「PEP 572が終わった今、二度とPEPのためにあれほど苦労し、多くの人が私の決定を嫌うようなことはしたくありません。意思決定プロセスから完全に身を引いたいと思っています。」批判はコミュニティ全体からだけでなく、コア開発者からも寄せられた。

彼らは、この演算子がPythonの禅に由来するPythonの基本原則、特に複雑さよりもシンプルさを優先する考え方に反すると主張しました。30年近くもの間、Pythonは紛れもない言語設計者として君臨してきましたが、これは一つの時代の終焉を告げるものでした。しかし、Pythonが新たなWalrus演算子を導入せざるを得なくなり、その過程でコミュニティが分裂する一方で、次のような疑問が生じます。他の言語は同様の概念をどのように扱っているのでしょうか?

Python演算子 := (代入式のエイリアス「Walrus」)はPHPには存在しません。なぜなら、これは必要ではないからです。PHPでは、代入演算子は = いつも 声明と表現を同時に: 代入は割り当てられた値を返します。これがまさに、「代入してテストする」といった慣用的なパターンが機能する理由です。 if- 独自の言語機能を持たない条件。

function get_some_field() {
    return 'foo';
}
if ($a = get_some_field()) {
    echo $a; // foo
}
// Hinweis: $a ist *gesetzt*, selbst wenn die Bedingung falsy wäre.

$a = get_some_field() 右側に代入して評価します。これが「真」の場合、 if-ブロック。背景: Pythonでは、 := (PEP 572) 単純な代入は式ではないためです。PHPではこの点は従来と異なるため、同等の必要はありません。バグの原因となることが多いのは以下の2点です。: = (代入) はほとんどの関係演算子よりも優先順位が低く、括弧によって評価が決定されます。

より複雑な式では、読みやすさと明瞭さを高めるために常に括弧を使用する必要があります。 ?? 優先度は低い。そのため、次のような表現に驚くことがある。 $x ?? null === null. 括弧なしで、まず null === null 評価されます。常に明示的に括弧で囲むことをお勧めします。: ($x ?? null) === null. $a 外にも存在する if-ブロック – 誤った値を持つ可能性があります。

function get_some_field() {
    return 'bar';
}
if ( ($a = get_some_field()) === 'bar' ) {
    echo $a; // bar
}

つまり、 === 'bar' 割り当てられた値に適用されます。括弧は可読性と優先度付けのために重要です。実際には、このパターンはクエリ結果を保存してからチェックすることで、不要な重複呼び出し(例えばクエリビルダーの呼び出し)を回避します。Laravelベースのプロジェクトなどの本番環境アプリケーションでは、以下のパターンがより頻繁に見られます。:

if ( ($foo = Foo::where('foo', 'bar')) && $foo->count() > 0 ) {
    dd($foo->get());
}

&& は短絡的です。右側の部分は左側の部分が真である場合にのみ評価されます。上流で文を代入することで、if文の外側で文を代入することを避けられます。これが良い方法かどうかは、チームのコードと分析ツールによって異なりますが、意味的には正しいです。少なくとも、実際にこのコードに遭遇した場合、そのコードが何を行うのか理解できるはずです。

PHPでは代入が既に式であるため、「Walrus演算子」は必要ありません。これにより、「代入してテストする」といった慣用的なパターンが、パフォーマンスと簡潔性を兼ね備えて可能になります。同時に、より厳格な記述が求められます。括弧、厳密な比較、真偽の区別、そして明確なチーム規約が必須となります。これらのガイドラインに従うことで、追加の言語機能を必要とせずにWalrus演算子のメリットを享受できます。

バック