Edited at

型付きPHP、P++のFAQ

以下はP++ idea: FAQの日本語訳です。

オーサーのZeev SuraskiはZendのZeで、ようするにPHPのすごい人です(特権とかは特にない)。


P++ idea: FAQ

これはinternalsで提示したアイデアに関するFAQです。

その後の議論で何度も提起された、多くの問題点に対処するものです。

P++は一時的なコード名であり、変更になる可能性があります。


What is this all about?

これは何?

短くまとめると以下のようなものです。

PHPの世界は、大きくわけてふたつの考え方があります。

まずひとつめは、PHPのアバウトで後方互換性が強力でシンプルさを重視しているところが好きな人々です。

もうひとつは、より高度で複雑な機能を持ち、古い文法は切り捨てる、厳密な言語を好む層です。

ここには「正しい」も「間違い」もありません。

どちらも意義のある考え方であり、どちらにも多くの支持者がいます。

しかし、これら両方の考え方を同時に満足できる言語を作成することは困難です。

これはinternalsで常に論争が発生する原因のひとつです。

この提案は、PHPと共に利用できる新たなPHPの方言を作ろうというものです。

この新たなPHPは、PHPの歴史哲学に縛られることはありません。

この方言は本家よりより厳密であり、後方互換性に縛られることなく、不要な要素はどんどん削除し、より複雑な機能、特に厳密な型付けといった要素を、PHP本家のような複雑さを伴わずに導入することができます。

これはforkではありません。

コードベースは同じであり、コードベースを利用する開発者も同じです。

コードの大部分は同一であり、特定の一部のポイントのみが異なる実装を持つようになります。

これはPHP7で導入されたstrict_typesと同じようなものであり、そしてそれよりは大規模なものです。


Do we really need to do all that just because some folks can't give up on short tags?

一部の人々がshort_open_tagを諦めることができないという理由だけで、こんな実装を行う必要がありますか?

このproposalはshort_open_tagとは無関係であり、そのRFCがこのproposalの動機になったわけではありません。

この提案の目標はもっと野心的で、PHPの明確なビジョンを示すことです。

そしてゆるふわPHPとガチガチPHPの両者を提供することで、最終的にはinternalsの両派閥の緊張を和らげることを願っています。


Why fork PHP?

これはforkではありません。

同じコードベースで管理され、同じバージョン管理され、同じ人々が開発し、同じバイナリで提供されます。

PHPをインストールすると同時にP++がインストールされ、その逆もまた然りです。

ひとつのバイナリでPHP、P++、そしてPHPとP++が混ざったソースを実行することができます。

あるPHPファイルがP++であることをどのように示すかはまだはっきり決まってはいませんが、おそらくファイル最上部に何らかのヘッダを記述することになるでしょう。

<?p++?>

<?php 'Hello, world!'; ?>

さらに、名前空間全体をP++であると一括指定する方法を考えているため、フレームワークなどは個々のファイルそれぞれにP++をマークしていく必要はありません。


This means doubling our dev efforts, while internals@ is already low on contributors. How will we deal with that?

internalsでの開発者が減少しつつある現在、開発工数が2倍になるのだが大丈夫か?

その指摘はまったく当たりません。

コードのほとんどは、PHPモードとP++モードで共用されます。

データ構造、主なサブシステム、エクステンション、Webサーバインターフェイス、OPcache、およびその他ほとんどにおいて、実行中のファイルがPHPであるかP++であるかに関わらず、全く同じコードが実行されます。

追加になる開発オーバーヘッドは、PHPとP++で異なる特定部分だけになります。

P++はPHPに比べるとチェックが増える可能性が高いため、一部のコードには2つのバージョンを維持するため多くのif文の追加が必要となることでしょう。

しかしながら、これは厳密なチェックを導入するためには、どうしても必要となる要素です。

ガチガチコードの最過激派においてさえ、移行段階を経ることなくいきなり厳密コードしか使えなくしようなどとは想定していません。

従って、このアプローチは、他の多くのRFCと同じような段階的取り組みだと言うことができます。


Why not just make a perpetual PHP 7.4 LTS and be done with it, as we move to a stricter PHP 8/9?

PHP7.4をLTSとして長期サポートし、PHP8/9は厳密モードだけにするのはどうでしょう?

このアプローチには多くの問題があります。

アバウトPHPを好む層は、今後の機能追加やパフォーマンス改善が見込めないとしてもPHP7.4に留まり続けます。

このproposalの意図と異なり、これは実質的にforkを意味します。


Will I need to choose between PHP and P++?

PHPとP++どちらかを選ぶ必要がありますか?

イエスでもあるしノーでもある。

前述したように、片方をインストールするともう片方も自動的にインストールされるので、ひとつのサーバで両方の方言を実行可能です。

しかし実際には、strict_types同様に、プロジェクトによってどちらかひとつを選択して使用する可能性が高いでしょう。


Will I be able to mix and match PHP and P++ in the same app?

ひとつのアプリでPHPとP++を混ぜて使用できますか?

はい、コードがPHPであるかP++であるかの判定は、リクエスト単位ではなくファイル単位で行われます。

正確な判定アルゴリズムはこれから検討する必要がありますが。

PHPファイルのコードはPHPセマンティクスで動作し、P++ファイルのコードはP++セマンティクスで動作します。

これはstrict_typesの動作とよく似ています。

これは最初は厄介そうに思えるかも知れませんが、こうすることで実用的な使用例が生まれます。

たとえばP++フレームワーク上でPHPのコードを動かす、あるいはその逆です。

CとC++の関係に、少しばかり似ています。


Does it mean PHP will no longer evolve? Will all new features go into P++?

PHPは進化しなくなりますか?全ての新機能はP++にだけ導入されますか?

いいえ。別々に進化するということを意味します。

厳密型に関する機能はP++だけに適用される可能性が高く、P++ファイルでのみ使用可能です。

互換性は維持されますが、今後決して壊れないという意味ではありません。

JITなどのパフォーマンス向上、エクステンション、非同期といった、厳密性と関係の無い機能はPHPとP++の両方で利用できます。


What are the benefits of this approach?

このアプローチの利点は何?

このアプローチには多くの利点があります。

まずinternalsやその他の場所にいる、両派閥陣営にともに良い解決策を与えます。

PHPの動的な仕組みを好む人はそちらを使い続け、厳密な型指定を好む人はそちらに移行することができます。

次善の策は、ゼロサムです。

すなわち、勝った派閥が全てを手に入れ、もう片方には何も残りません。

技術的に優れた解決策であるうえに、最小限の労力で使用者の全てをサポートすることができます。

また、近年のinternals戦争の主要な原因に終止符を打つことができるかもしれません。

最後に、このドキュメントの読者はほとんどが技術者であると思われますが、クリーンな状態から始まるP++にはポジショニングやブランディングに対する大きなアドバンテージが存在するでしょう。

言語仕様上の理由でPHPを選択対象から外した企業、上司、開発者は、PHP8や9のリリースよりP++のリリースに注目する可能性が高いでしょう。


Aren't we risking fragmenting the userbase?

ユーザのコードベースを分断する危険性はありませんか?

その可能性はあります。

しかし、それはこのアイデアの欠点ではなく、現在既に存在しているものです。

PHPの動的な性質を好む大勢の人がいて、彼らはPHPがどんどん型志向に向かいつつある現状を畏れつつ見守っています。

それと同時に、『このナンセンスな動的性質を排除するのにどうしてこんなに時間がかかるんだ』と考えている大勢の人がいます。

これはどちらが良い悪いということではありません。

この相反する両者とどちらも手を繋ぐための手段は、あまり多くありません。

・動的PHPを保つ:strict主義者には受け入れられません。

・厳格PHPに移行する:動的主義者には受け入れられません。

・forkする:これは純粋な損失です。技術的な利点はなく、それでなくとも開発者の手が足りません。

・両方を満足させる:このproposalがやろうとしていることです。プロジェクト自体は統一したまま、相互運用性を持つふたつの方言を維持します。コードの分散は避けられませんが、できるかぎり最小限に留めます。


How does this differ from Nikita's Editions idea?

NikitaのEditionsアプローチとの違いはなに?

彼の提案とは多くの類似点がありますが、意味的な違いが幾つか存在します。

Editionsアプローチを完全に理解できていないため、以下は不正確である、あるいは誤りがある可能性があることに注意してください。

・このproposalでは、動的型付けのPHPも維持するという明確な目標があります。

すなわち、長期にわたり最新機能を完全サポートしていく、PHPの方言です。

Editionsアプローチは、現在の動作をレガシーと見做します。

すなわち、ある時点で推奨されなくなり、いずれ削除される可能性があります。

・ロールアウト戦略は明確に異なります。

P++の場合、PHPと完全に互換性のない要素(厳密性、型操作ロジック、配列インデックス、変数定義など)に注力し、P++の初回インストール時にそれらを全て利用可能にすることを目指します。

すなわち、新たなプロジェクトやフレームワークをすぐに開始することができることを目標としています。

それ以降にふたたび互換性を損なう変更が導入されて、一年後すぐに大幅な書き換えが必要になる、といった事態を避けるためです。

Editionsアプローチでは、PHPの要素を徐々に追加・置き換えていく方針となっています。

・ロールアウト戦略に関連して、Editionsアプローチでは方言を2種類だけに限定していません。

PHP2020方言とPHP2022方言に加えて、PHP2027方言も増えていきます。

それら全てを維持するとなると、メンテナンスコストはさらに増大します。

・このproposalではPHPとP++の後方互換性に対する戦略についても言及していますが、Editionsアプローチはそのことについて特に触れていません。

・Editionsアプローチにはポジショニングやマーケティングの側面がありません。

2つのアイデアは決して排他的なものではないことに注意しましょう。

P++を導入し、それをEditionsアプローチで進化させることも可能です。

特に、最初のP++インストール時に全ての変更を取り込むのが困難だった場合など。


What are the challenges?

課題はなにがありますか?

課題は尽きません。

まずは人材を確保する必要があります。

このアイデアは、PHPが完全な動的型付けになればいいという人と、PHPが完全な静的型付けになればいいという人の目的を諦め、異なる考え方をする人の考えを受け入れる必要があります。

これは存外に大きな課題のようです。

このアイデアが成功するためには、P++の最初のバージョンは、PHPと互換性のなくなる変更点の全て、あるいは少なくともそのほとんどを実装していなければなりません。

ひたすらswitchを埋め込む作業はおそらく相当に苦痛だと思いますが、一度開発が終わってしまえばその後はコードを全面的にリファインする必要はなくなるでしょう。

我々の手持ちの開発力では、その開発を一度でやりきるのは楽観的すぎるという懸念をいくつも見ます。

開発項目のリストについて、よりよく理解する必要があります。

P++の最初のバージョンで全てのアイデアを実装する必要があるわけではないことに注意してください。

ユーザサイドの大幅なコード書き換えが必要になる要素のみを優先付け、最初のリリース時はそれだけを注力して処理することになります。

そして最後に、このチャレンジングな挑戦に相応しい、この方言の正式名称を決める必要があります。


This is Hack all over again, isn't it? Why would it fair any better?

これHackだよね?

概念としては、P++とHackの動機は似ていますが、両者には少なくとも二つの大きな違いが存在します。

Hackはボランティアによるオープンプロセスではなく、ひとつの企業によって開発されたものです。

いくら背後に巨大なベンダーを抱えていたとしても、企業や個人はしばしばそのことを嫌がりました。

より大きな違いとして、HackやHHVMには実行環境を広く配布する手段がありませんでした。

ユーザにとって、Hackを試してみるというのは骨の折れる仕事でした。

その存在を知り、十分な関心を持って調べなければなりません。

たとえ使いたいと思ったとしても、PHPとは全く異なる方法ゆえ、セットアップからして苦戦しなければなりませんでした。

P++は全く異なります。

PHPが使えるということは、すなわちP++が使えるということです。

何かをインストールしたり、何かをセットアップしたりする必要は全くありません。

あらゆるLinuxディストリビューション、あらゆるWAMP/MAMPを使用している全てのユーザが、PHPを最新バージョンにバージョンアップすれば、それがつまりP++が使えるということです。

ユーザの認識としては、PHP7のパフォーマンス大幅向上(ほとんどのPHPerはそれに気付いていません)と同じように、P++は『PHP8の新機能』の一部となります。

もちろん、誰もがそれをすぐに使い始めるわけではありませんが、P++への参入障壁は、Hackへのそれよりも桁違いに低いものとなります。


What are the general concerns?

全体的な懸念点は?

Arnold Danielsが懸念点をまとめました

ここではそのいくつかにおいて回答します。


Converting PHP code to P++ code is not trivial

PHPコードをP++に変換するのは簡単ではない。

それは確かですが、最終的にはP++がどこまで独自仕様を導入するかによって決まります。

このproposalの前提は、そもそもPHPを現在のPHPとは大幅に異なる、静的で強力な型付けに変更したいと考えている大勢の開発者がいるということです。

PHPをより動的で、緩やかな型付けにしたい人たちとのゼロサム戦争にしたいのでないかぎり、これは悪いことではないはずです。


PHP tooling will not support P++

ツールがP++をサポートしないのでは?

ベンダーにとっては、P++のサポートはdeclareをサポートするより簡単です。


It's not possible to do a cleanup without breaking PHP compatibility

PHPとの互換性を損なわずに型付ける方法がありません。

それは確かです。

しかし、むしろそれこそがこの新しい言語を導入する理由です。

厳格PHPの支持者の多くは、下位互換性を破棄してでもより大きな実を手に入れることを望んでいます。

これはすなわち、互換性を守っていきたい開発者との選択肢としては、ゼロサムゲームしかありません。

最近はこのような互換性を切る事例が散見されますが、将来的にはさらに多くの切り捨てが待ち受けています。

Andyが言及した一部事例に関して回答しておくと、

array()を削除してもP++やPHPの互換性は途切れません。それは[]のシンタックスシュガーです。

・関数のグローバル名前空間を削除すると、それはP++にのみ影響します。PHPでは引き続き存在します。

これらの回答は議論を経たものではないため、P++に導入されるかもしれないしされないかもしれません。


The popularity of Python doesn't have to do with typing

Pythonは型付けとは縁がないのに人気です。

このドキュメントおよびproposalでは、強い静的型付けが正しいとか悪いとかは一切主張していません。

どちらが正しいかではなく、PHPユーザには相反する二つの考え方が存在することを認めることです。

このproposalが行うのは、効率的かつ生産的に、二つの考え方の両方に対応する方法を提供することです。

強い型付けをより良い考え方だと考える人が多いので、そのオプションを備えるということは、彼らのモチベーションをアップさせることに繋がるかもしれません。


Is there really a need for a different dialect?

本当に方言が必要なん?

厳格原理主義者が求めているのは、より強く、より静的に型付けされた言語であることがすなわち進歩した言語であるということであり、そして主な障害は、それをどのように実現するかです。

クラウドをレガシーなPHP7.4に維持したまま、PHP8でそれを実現することが可能でしょうか?

目的地に到着するまで、数年ごとに少しずつ変更をリリースし続けますか?

しかし同時に、厳格陣営の開発者が求めているのは、単にstrict_typesのように実用的な厳格性を使いたいということです。

P++は誰にとっても後退ではなく進歩であり、特に強い静的型付け言語を好む人にとっては大きな進歩です。

これこそが我々が目指す方向になるでしょう。

すなわち、とにかく方言を利用できるようにするということです。

実のところ、方言を2^N個持つか(granular declare()s)、N個持つか(Editions)、2個持つか(PHP/P++)というだけの違いです。


感想

PHP internalsでは、アバウトゆるふわなPHPでありたい勢と、ガッチガチstrictなPHPにしたい勢による武力闘争が長らく続いており、P++はその戦争を終わらせる最終手段として投入されました。

なにしろMLのタイトルがBringing Peace to the Galaxyですからね。

結論としては両方やればいいじゃんということで、要するにJavaScriptにTypeScriptを抱き合わせセットにしちゃおうぜみたいな話です。1

strict_typesはPHPとの互換性を保った上でさらに厳密な記述を導入するというアプローチでした。

いわゆる上位互換であり、strict_typesなPHPは素のPHPでも完全に動作します。

しかしP++は、厳密性を導入する傍らで互換性を一部切り捨てます。

すなわち、P++のコードがPHPでは動かない、逆にPHPのコードがP++では動かない、といったことが発生します。

これまでのPHPの方針である『厳密に書くこともできる』を転換し、『厳密に書かなければならない』を強制するということで、なかなか思い切った方針転換ですね。

といっても適用はファイル単位なので、気分で使ったり使わなかったりが可能だったりはします。

ユーザ側としては、実のところstrict_typesとたいして変わらない使い方になりそうです。

あれば便利だとは思いますが、しかし、いくらforkではないと強弁したところで実装工数が相当に増えるのは間違いありません。

PHP本体の開発ですらわりかし手一杯なのに、そこからさらにP++にまで割くリソースがあるのかは正直疑問なところです。

特に、開発リソース不足を指摘しているのがかのNikitaですからね。

これからこのproposalをRFCにまとめ、投票で2/3の賛成を得て、軌道に乗るまで実装が進むか、というと相当微妙だと思います。

はい、現状これはRFCですらありません。

ただの思いつきのひとつに過ぎません。

個人的には、このproposalはRFCにすら辿り着かないか、RFCまで行ったとしてもDraftのまま塩漬けになるんじゃないかなと思います。





  1. TypeScriptはJavaScriptの完全上位互換なので、立ち位置はむしろstrict_typesかもしれない。