(jp) =
<!–
–>

私が最後に遭遇したのはいつだったか当ててみませんか? TypeError 私のプロジェクトの1つで? 正直、覚えていないので、おそらく数年ぶりです。 偶然にも、私も同じ頃に静的解析に頼り始めました。
PHP の実行時型チェックを完全に無効にすることができると確信しています (それが問題である場合)。
ランタイムの型チェックについては次のとおりです。これらはデバッグ デバイスであり、セーフティ ネットではありません。 実行時の型エラーにより、バグの検出と修正が容易になりますが、実際には、型エラーがトリガーされるたびに、実行時にコードがクラッシュします。 本番環境で型エラーが発生すると、最終的にプログラムがクラッシュし、どうすることもできません。
さて、以前型システムについて書いたことがありますが、この投稿の最後にいくつかの参考文献があります。 したがって、それらに関する背景情報が必要な場合は、必ずフォローアップを読んでください。 今日は、静的解析がどのように PHP コードの記述方法を今日よりも大幅に変革する力を持っているか、そしてそれがどのように多くの新しい可能性への扉を開くことができるかについて説明したいと思います。
トレードオフ? コミュニティ全体のマインド シフトが必要です。まだ多くの PHP 開発者 (内部開発者を含む) が、静的型チェックの考え方にびっくりしています。 今日の私の唯一の目標は、固定観念にとらわれずに考え、PHP が組み込みの静的型チェック モデルに移行した場合に何が可能になるかを想像するよう奨励することです。
静的型システムに興味があるかどうかに関係なく、興味深いものになることを約束します。 飛び込みましょう!
しばらく前に、PHP のジェネリクスがすぐには登場しないことが明らかになりました。 主な理由の 1 つは、それらを実装するには 2 つの方法があり、どちらにも重大な問題があるためです。 実行時のパフォーマンスへの影響が大きすぎるか、実装が複雑すぎて適切に処理できません。
ただし、どちらのアプローチも実行時の型チェックの実装を前提としていました。 ジェネリックの構文のみをサポートする必要があり、静的アナライザーにすべてのチェックを行わせる場合はどうなるでしょうか? 当時はトランスパイルされたジェネリックと呼んでいましたが、 ランタイム消去 また ランタイム無視 ジェネリックはおそらくより良い名前です。
私の考えでは、一般的な構文のサポートを追加することはそれほど難しいことではなく、実行時の型チェックがなければ、パフォーマンスに影響を与えるべきではないと考えていました。 静的解析の観点から考えると、それは理にかなっています。コードは既に解析されており、正しく動作することが証明されているため、実行時の型チェックはもう必要ありません。 その上、ほとんどの開発者は、より良いコードの洞察を得る方法としてジェネリックのみを望んでいます その間 コーディング; 「配列内の項目を知りたい」という引数はベルを鳴らしますか?
もちろんまだあるかもしれません いくつか リフレクションを介して実行時に型情報が公開されますが、実行時に型を無視することは、ほとんどの PHP 開発者が慣れていない主要なパラダイム シフトであることは否定できません。 これは、ランタイムを無視するジェネリックのアイデア (Hack が既に行っている) に対する Sara の応答と、それがどのようにマインドシフトを必要とするかです。
ああ、HackLang のアプローチには真の価値があることに同意します。 ただ、「PHP Way」の周りには慣性の山があり、進路を変えるには対等で反対の山が必要です。 完全に可能性があり、可能性も高いですが、今後5年間でそのレベルの変化は見られません.
あと数年かかりますが、おそらくPHPのやり方です 意思 サラによると、とにかく進化します。
さて、怒っている暴徒が私を追いかける前に: 実行する必要がある静的アナライザーを PHP にバンドルすることを提案しているわけではありません (これは、実際には「コンパイル」ステップを意味します)。 私は何 午前 必要に応じて PHP の実行時の型チェックを無効にし、その結果を自分で処理できることを示唆しています。 そのようなシナリオでジェネリックを使用する場合は、はい、静的アナライザーを使用する必要があります。 したくない場合は問題ありませんが、ジェネリックを使用することはできません。
もちろん、理想的な世界では、PHP にはそのような組み込みのオプトイン静的アナライザーが付属しています。 ユーザーがサードパーティのツールに頼る代わりに。 サードパーティ製ツールの主な問題は、ツール間の一貫性です。 適切な例: PhpStorm は、Psalm と PHPStan がそれらのサポートを追加してから数年後に、次のリリースでジェネリック型のドキュメント ブロックの基本的なフォームをサポートします。
内部でサポートされている公式の仕様があれば、静的解析ベンダーはその仕様に従うしかありません。 これが現時点での doc ブロック タイプ チェックの主な問題です。ルールがないため、すべてのベンダーが好きなことを行っています。
ところで、集中型の静的アナライザーのアイデアは新しいものではありませんが、正しく理解するのは大変な作業であることが想像できます。 数年前にこの問題について Rasmus が次のように述べています。
RFC がコンパイル時の静的解析エンジンを PHP 自体に組み込む計画だったとしたら、それは興味深いことです。 しかし、それは大規模なプロジェクトです。
実行時に無視される型とジェネリックの考え方についてニキータに尋ねたところ、彼はジェネリックの主な問題について次のように説明しました。 持ってる 次のようなランタイム実装:
複雑さは私たちにとってかなり大きな問題であり、非貢献者によってひどく過小評価されていると思います. 表面上は単純に見える機能の追加は、複雑さを膨らませる方法で他の既存の機能と相互作用する傾向があります。
彼はまた、ランタイムで消去されるジェネリックを「臆病者の抜け道」と呼びました。 ニキータがそう言う理由は、実行時に消去されるジェネリックがサポートされた場合、一部の部分は実行時にチェックされ、他の部分は静的にチェックされるという PHP の型システム内に大きな矛盾があることを意味するからです。
明確にするために、私はランタイム消去またはランタイム無視のジェネリックから始めるべきだとは思いません。 まず、実行時の型チェックがまったくない PHP が必要です。次に、その上に構築することを考えることができます。
そのようなバージョンの PHP にメリットがあると思うかどうか Nikita に尋ねたところ、彼は次のように述べました。
それは良いことだと思います…しかし、もう一度、白紙の状態で再設計を行うと、PHPで多くのことが異なります。 どうにかして、私たちが持っている制約の中で働かなければなりません。
ユーザーランド開発者の観点からは、 できる これらのアイデアをサポートする十分な規模のユーザー ベースがある限り、与えられた制約に従って動作します。
では、実行時の型チェックからオプションでステップを踏むことが達成可能であると内部関係者が考えていない場合はどうなるでしょうか? あるいは、そのようなマインドシフトが今後10年以内に起こらないとしたら?
さて、そこで は 別のアプローチで、以前に別の言語で実際に試行され、証明されたアプローチである TypeScript です。 TypeScript のパワーと絶大な人気は、その静的型チェッカーに由来します。 確かに、TypeScript コードを通常の JavaScript に変換するための追加のコンパイル手順がありますが、開発者は適切な静的解析からどれだけ得られるかを知っているため、それをうまく管理しているようです。
ちなみに、以前にPHPで同じことが試みられました:ある時点でハックがありました やりました PHPにコンパイルし、前処理、プロジェクトによるプロジェクトがありました クリストファー・ピット. 残念ながら、Hack は別の方向に進み、前処理は停止しました。 実装の問題ではなく、IDE やより広いコミュニティでのサポートの欠如が原因です。
もしも PHP のトランスパイルは再び勢いを増していますが、成功するチャンスがあれば、適切な IDE サポートが必要になることは間違いありません。 これが、内部に支えられた実装の利点です。それが PHP コアにある場合、IDE やその他の外部ツールは、従うことしかできません。 コミュニティ主導のトランスパイラーには、そのようなメリットはありません。
それで、これが今日の私たちの場所です:
- PHP のランタイム型チェッカーは限界に達しています (ジェネリックが最も明白な例です)。
- そこには それは すでに実行時に無視される型 (doc ブロック) ですが、静的解析コミュニティ全体で構文と使用法に関するコンセンサスはありません
- 実行時に無視される型には、多くの開発者がこの時点で難しいと感じるマインド シフトが必要です。
- PHP のトランスパイルは可能です。以前にも行われていますが、大規模な作業であり、適切なサポートなしで試行すると、再び失敗する可能性があります。
私は、静的分析の可能性がはるかに高いと考えています。 コードがより安定し、書きやすくなり、もはやこれなしではいられないほどになりました。 一方、コミュニティとツールセットにはまだ長い道のりがあり、私たちは皆、その旅の一部を担っています。
PHP の静的解析の側面を内部でさらに探求してもらいたいと思います。PHP は単なるユーザーランド アドオンではなく、将来的には PHP との緊密な関係が継続するだけです。
非現実的な期待であることはわかっていますが、今日の言語へのこれらの変更を見たいと思っています。 この点でサラの評価が正しいことを願っています は PHP が進化している形ですが、残念ながらそこに到達するにはあと数年かかるでしょう。 このブログ投稿は、正しい方向にもう 1 つプッシュする試みにすぎません。
あなたの意見は何ですか? お知らせ下さい.
# 補足
人々がこの投稿を読んでフィードバックを共有したら、おそらくこのセクションにさらに情報を追加しますが、すでにいくつかのことを考えることができます.
# 「トランスパイラー」としての Psalm + Rector ?
誰かが、Psalm と Rector の組み合わせを使用して、実行時の型チェックなしで PHP を使用するというアイデアについて言及しました。Psalm は最初にコードベースを分析し、その後、Rector はすべての型ヒントを削除して、「コンパイルされた」製品ビルドを生成しました。
これは、問題領域をさらに調査するための興味深いステップです。カスタム構文がサポートされているわけではありませんが、Psalm + Rector の組み合わせには可能性があるかもしれません。
# … を使わない理由は?
懐疑論者から聞かれる古典的な質問: 静的分析にそれほど依存したいのであれば、Java や C# などの言語を使用しないのはなぜですか?
答えは簡単です。エコシステムです。
#FIGはどうですか?
doc ブロック タイプの主な問題は一貫性の問題の 1 つですが、FIG で解決できるでしょうか?
最近の FIG の関連性については確信が持てません。たとえば、PhpStorm の開発に FIG が影響を与えるとは想像できません。 また、PSR のルールに従っている重要なフレームワークはほとんどありません。
それで、はい、多分? 私が間違っていると証明されたいです。
# Python はすでにこれを行っています
Python の型システム全体は、型消去に基づいて構築されています。 興味深いことに、私がここで提案していることは何も新しいものではありません。
//platform.twitter.com/widgets.js