解讀 PHP 的 P++提案

軒脈刃發表於2019-08-12

解讀 PHP 的 P++提案

週末看到一篇文章說 PHP 創始人提議將 PHP 拉出新分支,建立 P++ 語言。隨後閱讀了一下 Zeev Suraski 發起的這個郵件列表,大致瞭解了一下,這裡做個解讀。

Zeev Suraski 就是幾周前爆出的 PHP 核心開發者從 Zend 公司離職訊息裡面的主角。Zeev 是以色列的開發者。它也是 Zend 公司的聯合創始人。登陸它的 twitter 上看,它的 twitter 封面有個可愛的女兒,看來外國人也是很愛在社交賬號曬女兒的。

其實 PHP 現在大都由社群進行維護了,Zeev 的離職並不一定會有多少影響。

但是這次 Zeev Suraski 在社群中提的這個方案就引起了不少的反響。https://wiki.php.net/pplusplus/faq。 我們可以通過裡面的internal郵件 https://marc.info/?l=php-internals&m=156529545007909&w=2 檢視整個郵件線。

P++的方案

Zeev 的這封郵件的標題很有意思: Bringing Peace to the Galaxy。它希望這個idea 能給社群的強弱型別的爭端帶來和平,希望能解決強弱型別問題的爭論。

基本上 Zeev 是從如何發展 PHP 的角度考慮。現在 PHP 最大的分歧就是是維護動態語言,還是逐漸加入強型別的特性。基本上,如果要增加一些靜態語言的型別宣告和驗證,PHP 的向下相容性是得不到保證的。但是隨著 Rust, Go 等語言的衝擊,有一部分開發者逐漸傾向於使用一些強型別的特性。

那麼 Zeev 就認為,與其不斷在現有的 PHP 版本上對每個特性討論強弱型別的相容性,我不如讓 PHP 可以支援另外一種“新語法” P++。當然這個 P++ 只是暫定的。在 Zeev 的思考中,它認為 P++ 是一種增強型語言,但是和 PHP 是共存的。它們的呼叫關係就是 C 和 C++ 的關係,C++ 並不對 C 的所有語法相容,而是C++ 中是可以呼叫 C 程式碼的。換句話說,它覺得我們可以在一個程式碼檔案中共存兩種語法的程式碼段。可能示例如下:

<?php
xxx
?>

<?p++
?>

這樣做的好處有幾個,首先 PHP 的適用人群擴大了,它滿足了不同開發者的不同口味。其次,一些新的特性不用再考慮向下相容性了。在 P++ 中開發的特性等於是從頭開始開發,並不需要考慮 PHP 若干版本的歷史相容問題。會解放新特性的開發進度。

所以說,Zeev 並不是要開發一個新語言,也不是要從 PHP 分支 fork 出一個分支,更像是要建立一種新的語法分支,這個分支我理解主要是針對強型別限制的。而這個語法分支和原先的 PHP 是在同一份程式碼內。並且隨著每次 PHP 的版本,原先弱型別的 PHP和 新型別的 P++ 都會進行修復和增加。

另一種方案

但是緊跟著 Zeev 的這個郵件,Nikita Popov 回覆了這個郵件,它提出了反對的聲音,並且提出了自己的解決方法。

Nikita 的解決方法是參照 Rust 的版本管理,Rust 基本 2-3 年釋出一個大版本,但是 Rust 的編譯器能編譯所有版本的程式碼,所以每次釋出新版本的時候,如果你的程式碼是舊版本的,那麼還可以繼續編譯,且不會和新特性有衝突。 https://doc.rust-lang.org/edition-guide/editions/index.html#what-are-editions。Rust 到如今有兩個大版本了,2015版本和2018版本。

可以想象,如果引入 Nikita 的這種方式,需要在每個程式碼檔案中(或者粒度更細,到程式碼塊)中標記 PHP 的大版本版本號,比如用年號作為大版本號,今年2019是第一版本,也是預設版本,過兩年2021是第二版本。

Nikita 的這種方式目的是保持單一的 PHP 的語法分支,並且新特性也是不需要考慮向下相容問題。比如假設有2019版本和2021兩個 PHP版本。2021版本中語言的新特性在2019版本中是無法使用的。如果你想要使用這些新版本,開發者需要主動做升級修改。(可以想象到時候會有一些自動升級的指令碼)。但是如果你不想要修改,那麼就在你的所有檔案(或者配置)中說明我的專案使用的是2019版本(即使你現在使用的是 PHP 程式的版本是2021)。

後續

這封郵件後續的反饋基本都是針對這兩種方案展開的。Zeev 的方案基本的缺點就是需要維護兩個語言特性的分支,對於有限的語言開發者資源來說,是很吃力的。不少人會擔心最後演變成為 Python2 和 Python3 的現狀,長期無法合併。而且需要開發者在是使用PHP 語法還是P++ 語法做選擇。而 Nikita 的方案更有版本迭代的意味。

我個人更站邊 Nikita的這種升級,我覺得這種方案會有一種趨向性,最終大家會漸漸升級到新版本。且更容易落地,開發者只需要維護一套語言特性(相比於 Zeev 的方案更容易落地)。而 Zeev 的這種方案總是會給人一種老版本的 PHP 不想再去增加新特性,所有新特性都加在 P++ 這邊更好的感覺。漸行漸遠,我感覺最終還真會演變成大家都在開發新語言的態勢。

參考資料

https://marc.info/?l=php-internals&m=156535343921170&w=2
https://doc.rust-lang.org/edition-guide/editions/index.html#what-are-editions
https://nikic.github.io/
https://www.oschina.net/news/108717/zeev-leave-zend

相關文章