Skip to content

ext/standard: Implement list_filter() #18291

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

jorgsowa
Copy link
Contributor

@jorgsowa jorgsowa commented Apr 9, 2025

There are a few array functions that return arrays, without the option to return a list, even when we pass lists to them.

I would like to propose adding such functions to the core. One of them is list_filter() that is equivalent of array_filter(). I will prepare RFC later if the reception is positive.

Next functions would be:

  • list_diff
  • list_merge
  • list_unique
  • list_intersect

@TimWolla
Copy link
Member

TimWolla commented Apr 9, 2025

The correct choice is not to add more functions working on arrays only, but to add a proper iterable API: https://externals.io/message/118896#118896

I believe @iluuu1994 plans to work on it in the nearer future.

#18204 is also somewhat related.

@jorgsowa
Copy link
Contributor Author

jorgsowa commented Apr 9, 2025

I was also waiting for this to be released: #9882

But it's not moving forward, and we are getting new functions into the array API in the last PHP and probably the next one nayways.

@iluuu1994
Copy link
Member

The correct choice is not to add more functions working on arrays only

Tbf, at least unique() has some downsides when returning an iterator, namely that it needs to maintain a set of past elements internally anyway, so it might as well return this set, as Iter\toArray() would otherwise just copy this data to yet another new data structure. A similar issue applies to list_diff() and list_intersect().

I don't understand what list_merge() would even do.

I also think there might be some benefits to offering other list_ variants for singular transformations. This is likely faster than going through the iterator API. Of course, the downside is offering multiple solutions to similar problems, but as long as they each have their benefits I'm not too concerned.

@TimWolla
Copy link
Member

and we are getting new functions into the array API in the last PHP and probably the next one nayways.

Yes, but those are within the existing array_*() component. They do not introduce an entirely new list_*() component.

@TimWolla
Copy link
Member

Tbf, at least unique() has some downsides when returning an iterator, namely that it needs to maintain a set of past elements internally anyway, so it might as well return this set, as Iter\toArray() would otherwise just copy this data to yet another new data structure.

iterable\unique() could reasonably work on an infinite input iterable that is not fully consumed, for example this (using the proposed pipe operator with PFA):

function random_numbers() {
    for (;;)
        yield random_int(0, 99);
}

$fiveUniqueNumbers = random_numbers()
    |> iterable\unique(?)
    |> iterable\take(?, 5);

But generally speaking, the iterable\* functions should return the most appropriate type that still provides the necessary flexibility in implementation. The “iterable” part of the name is about the inputs, not the outputs. A iterable\reduce() or iterable\find() would not return iterables either, for obvious reasons. If a “lazy” iterable does not provide a value-add over an array, then returning an array is fine (arrays are also iterable after all).

I also think there might be some benefits to offering other list_ variants for singular transformations. This is likely faster than going through the iterator API. Of course, the downside is offering multiple solutions to similar problems, but as long as they each have their benefits I'm not too concerned.

Ideally the engine would be able to rewrite the code as appropriate, for example by fusing specific known combinations into more efficient functions or loops. iterable\take() could possibly be rewritten into a regular foreach loop without issue (no callbacks, thus no scoping issues).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants