Hi internals,
While reviewing various RFCs that introduce new functions, I noticed an
inconsistency: some authors include a userland polyfill (reference
implementation) in their RFCs, while others do not.
I wanted to open a discussion on whether we should strongly encourage RFC
authors to provide a PHP userland implementation when proposing new
standard library functions, where technically feasible.
Of course, I understand that this isn't possible for every new
function—especially those that interact with low-level OS APIs, memory
management, or internal engine features. However, for functions dealing
with arrays, strings, math, or general logic, I believe this has a couple
of major benefits:
- It clarifies the exact intended behavior, including edge cases and type
coercions, making the proposal easier to understand without diving into the
C implementation. - It immensely helps the community (e.g., the Symfony polyfill team) to
quickly and accurately port the function to older PHP versions once the RFC
is accepted.
Should we consider adding this as a standard recommendation (e.g.,
"Reference Implementation") in the official RFC template for applicable
functions?
I would love to hear your thoughts on this.
Best regards,
Sepehr
Hi internals,
While reviewing various RFCs that introduce new functions, I noticed an
inconsistency: some authors include a userland polyfill (reference
implementation) in their RFCs, while others do not.I wanted to open a discussion on whether we should strongly encourage
RFC authors to provide a PHP userland implementation when proposing new
standard library functions, where technically feasible.Of course, I understand that this isn't possible for every new
function—especially those that interact with low-level OS APIs, memory
management, or internal engine features. However, for functions dealing
with arrays, strings, math, or general logic, I believe this has a
couple of major benefits:
- It clarifies the exact intended behavior, including edge cases and
type coercions, making the proposal easier to understand without diving
into the C implementation.- It immensely helps the community (e.g., the Symfony polyfill team)
to quickly and accurately port the function to older PHP versions once
the RFC is accepted.Should we consider adding this as a standard recommendation (e.g.,
"Reference Implementation") in the official RFC template for applicable
functions?I would love to hear your thoughts on this.
Best regards,
Sepehr
Interesting idea. I think "recommended where relevant, but not required" is a reasonable policy to have. As noted, many RFCs don't have polyfillable features. For those where it is feasible, I think the "make it clear what the logic is" angle is the most compelling. (I often do that in the non-polyfill RFCs to help clarify the behavior.) And it would also give us a target to benchmark against to see if putting it in C really has a performance benefit.
--Larry Garfield
در تاریخ سهشنبه ۲۵ اوت ۲۰۲۶، ۱۹:۰۸ Larry Garfield larry@garfieldtech.com
نوشت:
Hi internals,
While reviewing various RFCs that introduce new functions, I noticed an
inconsistency: some authors include a userland polyfill (reference
implementation) in their RFCs, while others do not.I wanted to open a discussion on whether we should strongly encourage
RFC authors to provide a PHP userland implementation when proposing new
standard library functions, where technically feasible.Of course, I understand that this isn't possible for every new
function—especially those that interact with low-level OS APIs, memory
management, or internal engine features. However, for functions dealing
with arrays, strings, math, or general logic, I believe this has a
couple of major benefits:
- It clarifies the exact intended behavior, including edge cases and
type coercions, making the proposal easier to understand without diving
into the C implementation.- It immensely helps the community (e.g., the Symfony polyfill team)
to quickly and accurately port the function to older PHP versions once
the RFC is accepted.Should we consider adding this as a standard recommendation (e.g.,
"Reference Implementation") in the official RFC template for applicable
functions?I would love to hear your thoughts on this.
Best regards,
SepehrInteresting idea. I think "recommended where relevant, but not required"
is a reasonable policy to have. As noted, many RFCs don't have
polyfillable features. For those where it is feasible, I think the "make
it clear what the logic is" angle is the most compelling. (I often do that
in the non-polyfill RFCs to help clarify the behavior.) And it would also
give us a target to benchmark against to see if putting it in C really has
a performance benefit.--Larry Garfield
I'm really glad to see Larry's positive feedback. Looking forward to
hearing more thoughts from everyone else on this.
Best,
Sepehr
Hi Larry,
Thanks for the feedback!
I completely agree with the "recommended where relevant, but not required"
approach. Making it a strict requirement would be an unnecessary blocker
for features that simply can't be polyfilled.
Your point about benchmarking is spot on. Having a userland implementation
gives us a clear baseline to prove that the C implementation actually
offers a tangible performance benefit, which is often a key argument in
many RFCs. And as you mentioned, it acts as a perfect executable
specification to clarify the expected behavior.
Given this, do you think it would be worth adding a short note or
recommendation to the RFC HOWTO document? Just as a gentle encouragement
for future RFC authors to include a userland polyfill (or equivalent PHP
logic) when feasible.
Best regards,
Sepehr
در تاریخ سهشنبه ۲۵ اوت ۲۰۲۶، ۱۹:۴۴ سپهر محمودی sepehrphpr@gmail.com نوشت:
در تاریخ سهشنبه ۲۵ اوت ۲۰۲۶، ۱۹:۰۸ Larry Garfield larry@garfieldtech.com
نوشت:Hi internals,
While reviewing various RFCs that introduce new functions, I noticed an
inconsistency: some authors include a userland polyfill (reference
implementation) in their RFCs, while others do not.I wanted to open a discussion on whether we should strongly encourage
RFC authors to provide a PHP userland implementation when proposing new
standard library functions, where technically feasible.Of course, I understand that this isn't possible for every new
function—especially those that interact with low-level OS APIs, memory
management, or internal engine features. However, for functions dealing
with arrays, strings, math, or general logic, I believe this has a
couple of major benefits:
- It clarifies the exact intended behavior, including edge cases and
type coercions, making the proposal easier to understand without diving
into the C implementation.- It immensely helps the community (e.g., the Symfony polyfill team)
to quickly and accurately port the function to older PHP versions once
the RFC is accepted.Should we consider adding this as a standard recommendation (e.g.,
"Reference Implementation") in the official RFC template for applicable
functions?I would love to hear your thoughts on this.
Best regards,
SepehrInteresting idea. I think "recommended where relevant, but not required"
is a reasonable policy to have. As noted, many RFCs don't have
polyfillable features. For those where it is feasible, I think the "make
it clear what the logic is" angle is the most compelling. (I often do that
in the non-polyfill RFCs to help clarify the behavior.) And it would also
give us a target to benchmark against to see if putting it in C really has
a performance benefit.--Larry Garfield
I'm really glad to see Larry's positive feedback. Looking forward to
hearing more thoughts from everyone else on this.Best,
Sepehr
Hi
And it would also give us a target to benchmark against to see if
putting it in C really has a performance benefit.
I believe performance should not be a factor in deciding what should be
part of the stdlib and what should not: Performance is a moving target
and what might be true today might no longer be true tomorrow - with
folks generally having wildly incorrect assumptions about what actually
is “slow”.
Once we add something to the stdlib we need to maintain it for the next
15+ years. (Broad) usefulness and good API design must be the deciding
factors for whether something should be in the stdlib or not [1].
With PIE it has become easier than ever to build a custom extension for
one’s personal use cases to improve performance there.
Best regards
Tim Düsterhus
[1] It is debatable if the non-required bundled extensions are part of
the stdlib or not, for some of the more obscure ones like ext/tidy there
likely is a little more leeway in “just do it”.
Hi
And it would also give us a target to benchmark against to see if
putting it in C really has a performance benefit.I believe performance should not be a factor in deciding what should be
part of the stdlib and what should not: Performance is a moving target
and what might be true today might no longer be true tomorrow - with
folks generally having wildly incorrect assumptions about what actually
is “slow”.Once we add something to the stdlib we need to maintain it for the next
15+ years. (Broad) usefulness and good API design must be the deciding
factors for whether something should be in the stdlib or not [1].
I agree that good API design should be the primary factor. However, I disagree that performance is a non-factor. Yes, performance comparisons will shift over time, but that doesn't make it unimportant. It is one useful data point among many.
If, to use the current example, benchmarking shows that array_str_contains() is 50% faster in C than in user-space, that's a very different conclusion than if we find it is 0.5% faster. The former provides an argument for inclusion, though obviously not a slam dunk (as overall API design is a larger factor). In the latter case, we know that performance is a non-argument and can be dismissed.
We stress over the performance impact of certain generics approaches, we spent a lot of time thinking about performance implications for hooks, or PFA, or pipes. stdlib functions should not be exempt from that consideration. They should just be considered appropriately and in context.
--Larry Garfield
در تاریخ جمعه ۴ سپتامبر ۲۰۲۶، ۱۶:۳۴ Larry Garfield larry@garfieldtech.com
نوشت:
Hi
And it would also give us a target to benchmark against to see if
putting it in C really has a performance benefit.I believe performance should not be a factor in deciding what should be
part of the stdlib and what should not: Performance is a moving target
and what might be true today might no longer be true tomorrow - with
folks generally having wildly incorrect assumptions about what actually
is “slow”.Once we add something to the stdlib we need to maintain it for the next
15+ years. (Broad) usefulness and good API design must be the deciding
factors for whether something should be in the stdlib or not [1].I agree that good API design should be the primary factor. However, I
disagree that performance is a non-factor. Yes, performance comparisons
will shift over time, but that doesn't make it unimportant. It is one
useful data point among many.If, to use the current example, benchmarking shows that
array_str_contains() is 50% faster in C than in user-space, that's a very
different conclusion than if we find it is 0.5% faster. The former
provides an argument for inclusion, though obviously not a slam dunk (as
overall API design is a larger factor). In the latter case, we know that
performance is a non-argument and can be dismissed.We stress over the performance impact of certain generics approaches, we
spent a lot of time thinking about performance implications for hooks, or
PFA, or pipes. stdlib functions should not be exempt from that
consideration. They should just be considered appropriately and in context.--Larry Garfield
Thanks, Larry. I agree that performance is a relevant data point.
I have already conducted a real-world usage analysis, and the RFC now
includes both the summary table and a link to the complete JSON dataset.
I will also prepare a benchmark comparing the C implementation with
representative userland implementations (such as foreach loops and
array_filter-based approaches) across different array sizes and match
positions, and share the results.
Hi
We stress over the performance impact of certain generics approaches, we spent a lot of time thinking about performance implications for hooks, or PFA, or pipes. stdlib functions should not be exempt from that consideration. They should just be considered appropriately and in context.
Okay, let me spell out what was implied in my previous email:
Performance considerations are asymmetric. If something is too slow,
this is a problem and means that it can't ship. However this only
affects the specific implementation - it is entirely possible to build a
faster implementation of the feature in question based on the accepted
semantics. Though in some cases the semantics inhibit a faster
implementation - or make it hard to create one. These considerations
obviously also apply to the stdlib functionality and not just language
features.
On the other side we would not ship something just because it’s fast.
And that is also independent of whether it’s stdlib or a language
feature (such as erased generics, which are fast, but have language
design arguments against).
Or in short: Performance is a property of the implementation, not a
property of the feature.
Best regards
Tim Düsterhus
Hi
We stress over the performance impact of certain generics approaches, we spent a lot of time thinking about performance implications for hooks, or PFA, or pipes. stdlib functions should not be exempt from that consideration. They should just be considered appropriately and in context.
Okay, let me spell out what was implied in my previous email:
Performance considerations are asymmetric. If something is too slow,
this is a problem and means that it can't ship. However this only
affects the specific implementation - it is entirely possible to build a
faster implementation of the feature in question based on the accepted
semantics. Though in some cases the semantics inhibit a faster
implementation - or make it hard to create one. These considerations
obviously also apply to the stdlib functionality and not just language
features.On the other side we would not ship something just because it’s fast.
100% agreed on this point.
And that is also independent of whether it’s stdlib or a language
feature (such as erased generics, which are fast, but have language
design arguments against).Or in short: Performance is a property of the implementation, not a
property of the feature.Best regards
Tim Düsterhus
I think we're saying almost the same thing, from different directions. Performance alone is not an argument for a feature, but can be a contributing factor. Performance alone MAY be an argument against a feature, depending on the feature, but there are still many other factors to consider.
So I restate my original point: When adding a function/class/thing to stdlib that could be implemented in user-space (not everything can be), knowing the relative performance difference is a useful data point to have, but it is not itself a decisive argument for or against the feature.
--Larry Garfield
Hi
And that is also independent of whether it’s stdlib or a language
feature (such as erased generics, which are fast, but have language
design arguments against).Or in short: Performance is a property of the implementation, not a
property of the feature.I think we're saying almost the same thing, from different directions. Performance alone is not an argument for a feature, but can be a contributing factor. Performance alone MAY be an argument against a feature, depending on the feature, but there are still many other factors to consider.
The “almost” does some heavy lifting there, I believe.
I disagree that performance should be a contributing factor to whether
or not a proposal is good, because performance is a property of the
implementation and implementation is not what is being discussed and
voted on as part of the RFC process.
knowing the relative performance difference is a useful data point to have
I disagree, because it rarely is an apples to apples comparison (bad
userland vs good internal implementation and vice versa) and it ignores
other possible solutions to fix a performance problem, for example
improving the Optimizer to detect specific patterns and to transform
them into equivalent, but faster code.
Using the featured RFC which proposes a function that effectively just does:
array_filter($values, str_contains(?, 'foo'));
as an example, an alternative improvement to investigate would be
replacing calls to array_filter() with PFA by a foreach loop:
$result = [];
foreach ($values as $key => $val) {
if (str_contains($val, 'foo')) $result[$key] = $val;
}
similarly to the array_map() transform that is already included in PHP
8.6.
Best regards
Tim Düsterhus
Hi Sepehr
Le mar. 25 août 2026 à 13:21, سپهر محمودی sepehrphpr@gmail.com a
écrit :
Hi internals,
While reviewing various RFCs that introduce new functions, I noticed an
inconsistency: some authors include a userland polyfill (reference
implementation) in their RFCs, while others do not.I wanted to open a discussion on whether we should strongly encourage RFC
authors to provide a PHP userland implementation when proposing new
standard library functions, where technically feasible.Of course, I understand that this isn't possible for every new
function—especially those that interact with low-level OS APIs, memory
management, or internal engine features. However, for functions dealing
with arrays, strings, math, or general logic, I believe this has a couple
of major benefits:
- It clarifies the exact intended behavior, including edge cases and type
coercions, making the proposal easier to understand without diving into the
C implementation.- It immensely helps the community (e.g., the Symfony polyfill team) to
quickly and accurately port the function to older PHP versions once the RFC
is accepted.Should we consider adding this as a standard recommendation (e.g.,
"Reference Implementation") in the official RFC template for applicable
functions?I would love to hear your thoughts on this.
Best regards,
Sepehr
In case you didn't know, every polyfill-able feature ends up eventually in
one of the symfony/polyfill-* packages, all centralized in the
https://github.com/symfony/polyfill monorepo.
In my experience, this works quite well and I wouldn't require RFCs to ship
a polyfill: authors should be focused on the C implementation. The PHP
polyfill is not always trivial to achieve, and polyfills proposed in RFCs
don't necessarily end up being the ones shipped via symfony/polyfill, eg
because edge cases or perf improvements.
Polyfill needs a separate workflow.
Cheers,
Nicolas
در تاریخ پنجشنبه ۲۷ اوت ۲۰۲۶، ۲۰:۰۲ Nicolas Grekas <
nicolas.grekas+php@gmail.com> نوشت:
Hi Sepehr
Le mar. 25 août 2026 à 13:21, سپهر محمودی sepehrphpr@gmail.com a
écrit :Hi internals,
While reviewing various RFCs that introduce new functions, I noticed an
inconsistency: some authors include a userland polyfill (reference
implementation) in their RFCs, while others do not.I wanted to open a discussion on whether we should strongly encourage RFC
authors to provide a PHP userland implementation when proposing new
standard library functions, where technically feasible.Of course, I understand that this isn't possible for every new
function—especially those that interact with low-level OS APIs, memory
management, or internal engine features. However, for functions dealing
with arrays, strings, math, or general logic, I believe this has a couple
of major benefits:
- It clarifies the exact intended behavior, including edge cases and
type coercions, making the proposal easier to understand without diving
into the C implementation.- It immensely helps the community (e.g., the Symfony polyfill team) to
quickly and accurately port the function to older PHP versions once the RFC
is accepted.Should we consider adding this as a standard recommendation (e.g.,
"Reference Implementation") in the official RFC template for applicable
functions?I would love to hear your thoughts on this.
Best regards,
SepehrIn case you didn't know, every polyfill-able feature ends up eventually in
one of the symfony/polyfill-* packages, all centralized in the
https://github.com/symfony/polyfill monorepo.In my experience, this works quite well and I wouldn't require RFCs to
ship a polyfill: authors should be focused on the C implementation. The PHP
polyfill is not always trivial to achieve, and polyfills proposed in RFCs
don't necessarily end up being the ones shipped via symfony/polyfill, eg
because edge cases or perf improvements.
Polyfill needs a separate workflow.Cheers,
Nicolas
Thanks Nicolas, that makes total sense. I will focus entirely on the C
implementation.