P++ 的想法: 常见问题
原文: https://wiki.php.net/pplusplus/faq
日期: 2019-08-09 作者: Zeev Suraski, zeev@php.net 这是一份对在 internals@译注1 上提出的想法的常见问题澄清,它试图解决许多在随后讨论中被重复提出的问题。
注:P++ 是一个临时代码命名,未来可能会变化。
这到底是怎么回事?
试图将冗长的邮件内容浓缩为几点:
- PHP 世界有两个大的阵营。第一个大约是喜欢 PHP 的动态性,带有强烈的 BC译注2 偏见,并特别强调简单性,另一个更喜欢减掉包袱,拥有更高级、更复杂功能的更严格的语言。
- 这里没有“对”或“错”。这两种流派都有效,并具有非常坚定的追随者。然而,创建一种同时迎合这两个阵营的语言则是一项挑战,这也是 internals@ 上争论的一贯的原因。
- 该提议是创建一种新的 PHP 方言(代码名 P++),与 PHP 并存,但不受语言背后的历史哲学约束。换句话说,这种新方言本质上可能更加严格,它可能会更加大胆地消除向后兼容,并删除被认为是“包袱”的元素(例如短标签),并添加更复杂的特性,尤其是那些非常适合严格类型化的语言的,而无需为 PHP 方言引入相同的复杂性。
- 这不是 PHP 代码分支。代码库将是同一个,在该代码库上工作的开发人员是相同的。绝大多数代码都是相同的。只有两种方言之间的特定差异点才会有不同的实现。它有点类似于 PHP 7 中的 strict_types 所做的,只是在更大的范围内。
我们真需要做所有的那些事仅仅因为有些人不能放弃短标签吗?
这与短标签无关,“弃用短标签 RFC译注3 ”不是这个想法的主要动力。这个提案的目标是更有野心,它是为 PHP 提供一个清晰的愿景,并希望通过向两个阵营提供他们想要的东西来最终解决两方的紧张关系。
为什么要分叉 PHP?
这不是分叉。 代码库将完全相同,它将由相同的人开发版本。二进制文件将完全相同,如果你安装 PHP,你也将安装 P++,反之亦然。相同的二进制将运行 PHP,P++ 或组合 PHP/P++ 的应用程序。
虽然目前还不清楚如何将一个文件“标记”为 P++ 文件,但它可能是文件顶部的某种特殊标记,例如:
<?p++?> <?php 'Hello, world!'; ?>
此外,我们可能会找到将整个命名空间标记为 P++ 的方法,因此,框架不必将每个单独的文件明确标记为 P++。
这意味着我们的开发工作量增加了一倍,而 internals@ 的贡献者已经很低了。 我们如何处理?
值得庆幸的是,这并不意味着是那样(工作量增加了一倍)。绝大多数代码将在 PHP 模式和 P++ 模式之间共享——包括源代码和运行时。
无论运行的文件是 PHP 还是 P++文件,数据结构、关键子系统、扩展、Web服务器接口、OPcache 以及其他所有代码都将是完全相同的代码。唯一的额外开发开销会是 PHP 和 P++ 之间的差异部分。
确实,这意味着我们必须维护某些代码片段的两个版本,并且我们在各个地方都会有一些 if() 语句,因为与 PHP 相比,P++ 可能会有额外的检查。 但是,如果我们要转向更严格的 PHP 版本,这些元素无论如何都必须引入。此外,即使是严格阵营中的人,也不建议我们在没有提供迁移途径的情况下转向未来严格版本——实际上,这种方法所涉及的努力和几乎任何其他的方法都是相似的。
当我们转向更严格的 PHP 8/9 时, 为什么不只是开发一个永久维护的 PHP 7.4 长期维护版?
这种方法存在许多问题,但这些问题可能是最重要的问题:
- 对于动态人群,更严格并不等于进步,因此他们不希望看到 PHP 的未来版本迫使他们朝这个方向发展。他们仍然希望获得其他类型的新功能(非严格性相关),更好的性能,错误修复,新扩展等。在新版本中让 PHP 更严格,对于许多用户而言,这种升级就他们的开发偏好意味着倒退。
- 同样重要的是,从开发工作的角度来看,它非常困难,可以说是不切实际的。与此提案不同,旨在继续支持同一代码库中的两种方言,具有不再积极开发的版本,但仍需要在十多年的时间内保持安全性和关键错误修正,我们根本没有所需的资源(它可以说是一种分叉)。
我需要在 PHP 和 P++ 之间做出选择吗?
是和不是。 如上所述,当你安装一个,你就有了另一个,所以就应用而言,你可以在一台服务器上运行这两种方言。 然而,实际上,项目和个人通常可能选择并标准化其中一个,类似于严格类型的情况。
我能在同一个应用程序中混合使用 PHP 和 P++ 吗?
是的。 虽然我们需要确定精确的机制,但代码是 PHP 还是 P++ 的指定将在文件级别,而不是在请求级别。 单个执行(请求)可以加载许多不同的文件,这些文件可以来自两种方言。PHP文件中的代码将表现为 PHP 语义——而来自 P++ 文件的代码将表现为 P++ 语义。 这也是,与 strict_types 类似。
虽然这开始听起来可能听很尴尬,但可能会有非常实用的用例。例如,PHP 应用程序使用的只含 P++ 的框架,反之亦然。 对于那些熟悉 C 和 C++ 的人来说,这有点类似。
这是否意味着 PHP 将不再发展? 所有新功能都会用于 P++ 吗? 这是否意味着 PHP 将不再发展? 所有新功能都会用于 P++ 吗?
不,这只是意味着它会以不同的方式发展。 严格性和类型相关的功能可能只适用于 P++,并且只能在 P++ 文件中使用。向后兼容偏差将保留在 PHP 中(这并不意味着向后兼容永不会被打破,只是每个这样的案例必须有良好的投资回报案例)。
但是,与此无关的功能,例如引擎的性能改进(如 JIT ),扩展的开发,或新的异步相关的功能,PHP 和 P++ 都可以使用。
这个方法有什么好处?
这种方法有很多好处。 首先,它为 internals@ 的两个阵营提供了一个很好的解决方案。 那些喜欢 PHP 动态特性的人可以保留它,而那些喜欢更严格类型语言的人也可以获得它,而不受任何 PHP 限制。 而替代方案是零和游戏,一个阵营的胜利是另一个的失败,反之亦然。
除了设计一个好的技术解决方案(使我们能够以最少的努力支持整个受众)之外,还可以终结近年来 internals@ 上争论的关键根源。
最后,虽然本文档的大多数读者可能是技术人员,但应该注意的是,启动 P++ 将从一个新的基点译注4不计过去重新开始,可能具有巨大的定位和品牌优势。未使用 PHP 的公司、开发经理和个人开发者更有可能注意到 P++ 的推出,而不是 PHP 8.0 或 PHP 9.0 的推出。
我们不是冒着分裂用户群的风险吗?
在某种程度上,我们是。但这不是这一想法的缺陷, 而是现实已经存在的表现。
如上所述,那里有很多人喜欢 PHP 的动态本质,并且谨慎地看待尝试使其越来越多地面向类型。
与此同时,还有另外一群看着 PHP 的人,自己在想:“为什么它变得如此缓慢,以至于我最终要放弃这动态的废材译注5?”
这里没有对或错。这两种观点都有效。当我们研究在这两个相互矛盾的观点之间架起桥梁的可能的解决方案时,没有太多可用的方案:
- 坚持使用动态 PHP。这将不会被更严格语言的支持者所接受。
- 向严格的 PHP 发展。动态语言的支持者不会接受这一点。
- 分叉代码库。无论如何完成,都是所有参与者的净损失选项。 这样做没有技术优势,即使我们想要(我们不想要),我们也没有足够的贡献者去做。
- 提出一些创意解决方案,以满足双方观众的需求。 这就是该提案试图做的。它在保持项目本身统一的同时,也确保两种方言之间的永久互操作性。这虽然会有一定程度的碎片化,但它仍然是满足每个人的主要需求的最小可能。
这与 Nikita译注6版本的想法有何不同?
这两个想法之间有许多相似之处,但也存在一些实质性差异。 请注意,这是基于对版本方法的有限理解,因此部分可能缺乏,不准确或不正确。
- 在这个提议中,有一个明确的目标是保持当前动态类型的 PHP,作为一个长期的,完全支持的,平等的对等方言。 发版本的方法将当前行为视为“遗留”。 这意味着它可能会被劝止(使用),然后在某些时候弃用和删除。
- 推出策略完全不同。 P++ 提案旨在首先关注兼容性破坏元素,例如严格的操作、类型转换逻辑的更改、数组索引处理、需要变量声明等等,并且旨在在 P++ 的第一期提供它们。这样做的目的是允许新项目/框架重新开始,而不需知道在引入更多兼容性更改时,他们可能不得不在一两年内进行重大改写。 版本化提案似乎没有这样的目标,而是旨在逐步添加/更改 PHP 中的元素。
- 与推出方式相关,版本化方法不允许只有两种方言,而是任何数量的方言。我们可能有 PHP 2020 方言,以及 PHP 2022 方言和 PHP 2027 方言。 如果我们全部保留它们,实际上这可能会增加我们的维护复杂性。
- 该提议还提到了 PHP 与 P++(保守与积极)的不同打破向后兼容策略,而版本化方案可能根本不会涉及该主题。
- 版本提案与此提案的定位/营销方面并不完全相同。
重要的是,要注意这两个想法不一定是相互排斥的。 我们可以介绍 P++ 并使用版本进行改进,特别是当证明很难将所有重要的变化都放到 P++ 的第一期中。
有哪些挑战?
在我们能运行第一个 P++ 应用程序之前,不乏挑战。
- 我们需要获得支持。这意味着,两派的人都需要放弃让 PHP 完全动态或完全类型化的梦想,而忽略那些与他们想法不同的人。这似乎是一个非常重大的挑战。
- 为获得成功,P++ 第一个版本应该处理来自 PHP 的所有,或至少大多数兼容性破坏的更改,以便切换(可能相当痛苦)的开发人员不必在未来重新审核/彻底重构他们的代码。一些人表示担心,由于我们的开发人员能力有限,他们可能过于乐观,无法在一期发布。一旦我们对列表的内容有了更好的了解,我们就必须对此进行评估。 请注意,这并不意味着我们需要在第一个期中实现我们可能对 P++ 提出的所有想法,只是我们应该优先考虑会触发大量最终用户代码重写的元素,并尝试在我们的第一版之前处理它们。
- 当然,最具挑战性的——我们需要为这种新方言找到一个合理的名字。
这又是个 Hack译注7,不是吗? 为什么公平会更好呢?
虽然从概念上讲,P++ 和 Hack 的动机相似,两者之间至少有两个关键差异, 每个都可能足够大,足以改变预期的结果。
- Hack 是由一家公司开发的,而不是志愿者开放的过程。 即使背后的供应商是巨大的,公司和个人通常也不愿意在这样的平台上实现标准化。译注8
- 也许更重要的是,Hack(和 HHVM)没有 PHP 巨大的分发迭代。
- 对于 Hack,对用户来说甚至只是来个尝试,也是一场艰苦的战斗,:
- 他们必须了解它的存在,并有足够的兴趣去更多地了解它。
- 假设他们有足够的兴趣尝试它,他们不得不去经历麻烦地安装它,使用和他们平时习惯的 PHP 完全不同的方法(不同的布局,不同的配置,不同的一切)。
- 使用 P++,这是一个从头开始完全不同的故事:
- PHP 的每个用户(从 8.0 开始,或每当我们提供它时), 他们的服务器都会提供它。你不必安装任何东西,或者设置任何东西,它就会简单的在那里。
- 这反过来意味着,几乎任何运行 Linux 发行版(WAMP 的最新版)的 MAMP 的最新版本的任何人,都将可以访问 P++,而无需主动执行任何操作。
- 在意识方面,由于 P++ 将成为“ PHP 8 中新功能” 的重要组成部分,它将享受像 Hack 一样梦寐以求的免费营销,类似于 PHP 7 的性能飞跃(PHP 世界中很少有人不知道它)。
- 当然,这并不意味着每个人都会想要开始用它,但是使用 P++ 进入的障碍比 Hack 要面对的要低许多数量级。
一般关注什么?
Arnold Daniels 整理了一份有关这个建议的关注清单。
其中一些回答如下:
将 PHP 代码转换为 P++ 代码并非易事
这可能是真的,但它最终取决于我们决定放什么内容到 P++。该提议假设我们想要做的事情的内容是相似的,无论我们是使用 declare()s 方案,版本化方案,还是统一的 P++ 方言提供它。这个提议的前提是,PHP 世界中有很多人想要改变 PHP,使其与现在的方式大不相同,使其变得越来越强大和静态类型。假设这不是坏事,只要不将它视为与那些想要保持 PHP 更加动态和弱类型的零和游戏。
PHP 工具不支持 P++
从技术上理解这一点非常重要,实际上,供应商支持 P++ 比支持粒度声明 declare()s 或无限数量的版本稍微简单一些。 没有理由认为它的处理方式与使用不同机制引入和提供类似功能/变更的方式不同。
在不破坏 PHP 兼容性的情况下进行清理是不可能的
这是事实,但这实际上是考虑引入这种新方言的一个很好的理由,而不是相反。许多严格的支持者也希望在打破兼容性方面取得更大的飞跃。今天,没有其他选择,除了与那些可能不喜欢破坏 BC 的人们的零和游戏(特别是如果它是为了使 PHP 更严格)。最近有很多这样的事例,似乎还有更多的事实存在于未来。
关于 Andi 提出的具体例子:
- 删除 array() 对 P++/PHP 的兼容性没有影响,它只是更现代的 [] 语法的语法盐。
- 删除函数的全局命名空间(如果我们这样做)只会影响 P++ 代码(即删除它的访问权限),它仍然存在于 PHP 代码中。
重要的是要强调,这些想法到目前为止都没有被讨论过,并且可能会或可能不会被提议用于将来包含在 P++ 中。
Python 的流行与类型无关
这份文件,以及一般的提案,并未声称强/静态类型是一个好主意或坏主意。故意不站边哪一方是“正确的”。它所做的是承认 PHP 用户有两种基本上相反的思想流派,并提供了一个关于项目如何发展以便以有效和高效的方式解决这两个问题的建议。也就是说,显然,有很多人认为强类型的 PHP 会是更好的选择,所以拥有这个选项可能确实会增加它的受欢迎程度。
真的需要一种不同的方言吗?
许多“严格”阵营似乎相信的公理之一,是更强的类型和更静态类型的语言意味着进步,而主要的问题是,我们如何能够实现它,我们可以在 PHP 8 中完成它,同时保持动态群体在传统的 7.4 版本上吗? 我们是否应该通过每隔几年发布一次更改来逐步实现,直到我们达到我们想要的? 对于那些人群,需要明确的是,对于那些喜欢动态,弱类型的语言的人来说,强类型和静态类型并不是进步,而且无论是在一夜之间还是在十年内发生都无关紧要。
与此同时,许多其他专业人士更加务实,并希望简单地添加可选的严格性,与 strict_types 一致。 这可以说,可称之为进步,对于任何人来说都不是倒退,它确实为喜欢更强类型/静态类型语言的人提供了进步。这将可能是我们前进的方向,它意味着我们已经有了不同的方言。这真的是个问题,我们是否有 2^N 方言(granular declare()s),N 个方言(版本)或 两个(PHP/P++)。
pplusplus/faq.txt · 最后修改: zeev 于 2019/08/12 13:24
译注
- internals@:PHP 内部开发人员邮件列表。这里涉及 PHP 的开发机制,当内部讨论成熟后,会公开在 externals,通常用来提交 RFC 和发布版本通知。
- BC:即 Backward Compatibility,向后兼容,也叫向下兼容,兼容过去的版本,即升级的软件要考虑旧版本的兼容性,比如,Office 2019 的 Word 默认使用 .docx 文件格式,但也可以打开 Office 2017/2013/2010,甚至是 2003 的 .doc 格式。相对的概念叫做 FC,即 Forward Compatibility,向前兼容,也叫向上兼容,即升级的软件会考虑对未来的兼容性。这在软件中通常为一个确定的接口和约定,未来依然遵循,即可实现向前兼容。
- RFC:即 Request for Comments,语言特性的加入,以及标准化变更管理的方法,通常加入新特性时,会为新特性提交 RFC 并给出例子,变更委员会评估通过后,语言会合入实现的源码,并入新版本。
- 新的基点:a clean slate,美国习语,即不计过去新的开始。
- 动态的废材: dynamic nonsense,这是一句抱怨,但期待读者提供更准确的翻译。
- Nikita:internals@ 上的发言者,PHP 核心开发提议在小版本中加入特性。
- Hack:本意是乱砍,在计算机世界里的意义是,用不常规的方式解决问题,一般是技术大牛能做到的,MIT 精神。Hacker 黑客这个词即出自此意。
- 作者此句供应商指的 Facebook
(本文翻译保留了原文所有的格式,限于水平有限,如翻译中有不妥的地方请回复留言,如转载请注明出处:IT桃花岛)