Skip to content

Implement iterable_to_array() #3293

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

Closed
wants to merge 1 commit into from
Closed

Conversation

Majkl578
Copy link
Contributor

@Majkl578 Majkl578 commented Jun 13, 2018

iterable type is gaining popularity, unfortunately it is sometimes hard to work with. Especially when the output is needed to be converted into an array, as array_*() functions don't accept iterable, only plain array.

The proposal is simple: add iterable_to_array($iterable) sibling function to iterator_to_array($iterator) which will work with iterable (array or Traversable).

Before:

- is_array($iterable) ? $iterable : iterator_to_array($iterable)

After:

+ iterable_to_array($iterable)

This would be really convenient together with iterable typehint. 😊


Implemented:

  • iterable_to_array()
  • iterable_count()

Copy link

@jwage jwage left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 would love to see this

if (spl_iterator_apply(obj, use_keys ? spl_iterator_to_array_apply : spl_iterator_to_values_apply, (void*)return_value) != SUCCESS) {
zval_ptr_dtor(return_value);
if (zend_is_iterable(iter) == 0) {
zend_type_error("Argument 1 passed to iterable_to_array() must be iterable, %s given",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't we have this treatment in ZPP?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There doesn't seem to be a type specifier for iterable currently: http://php.net/manual/en/internals2.funcs.php
Also checked source directly and didn't see anything obvious. :/

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should add it :)

@linaori
Copy link

linaori commented Jun 13, 2018

Why as a developer should I care about the difference between iterable and Iterator? It would make a lot more sense to me to use iterator_to_array for the iterable type as well

@Majkl578
Copy link
Contributor Author

Majkl578 commented Jun 13, 2018

@iltar iterable is not an iterator, it's a union of iterator or array - polluting existing API didn't seem like a wise decision to me.

@carusogabriel
Copy link
Contributor

carusogabriel commented Jun 13, 2018

It would make a lot more sense to me to use iterator_to_array for the iterable type as well

@iltar Change a method signature is a no go for me 👎

@linaori
Copy link

linaori commented Jun 13, 2018

While I do agree with this additional function (would make a nice addition to 7.3), I believe there's a still a DX issue to have a different implementation, meaning 2 functions that seemingly do the same. I highly doubt that many developers know the differences between them and they won't know when to use which, making it confusing to use.

If iterable is Iterator|array, then wouldn't it make sense to deprecate the other function? If I understand your tests correctly, that also works now.

@Majkl578
Copy link
Contributor Author

wouldn't it make sense to deprecate the other function?

Maybe, but deprecating core function would require RFC while just adding this self-contained one shouldn't.


$array = ['a' => 1, 'b' => 2, 'c' => 3];
$iterator = new ArrayIterator($array);
$generator = function () use ($array) { yield 'a' => 1; yield 'a' => 2; yield 'a' => 3; };
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use ($array) seems unnecessary.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right! I originally had yield from $array; there. 😉

@Majkl578 Majkl578 force-pushed the iterable_to_array branch from 3563f38 to 018de8b Compare June 13, 2018 18:21
@Ocramius
Copy link
Contributor

Adding a new API seems like a sensible choice - the old one being deprecated later on is probably a good idea over changing existing behaviour

@cmb69
Copy link
Member

cmb69 commented Jun 13, 2018

Maybe, but deprecating core function would require RFC while just adding this self-contained one shouldn't.

Hm, since this appears to be controversial, an RFC might be the best way to go, anyway.

PS: Considering that a userland implementation of iterable_to_array() is basically a one-liner (see the OP), in my opinion an RFC is a must.

@Majkl578
Copy link
Contributor Author

Majkl578 commented Jun 14, 2018

Considering that a userland implementation of iterable_to_array() is basically a one-liner (see the OP), in my opinion an RFC is a must.

Hmm, technically I don't see any correlation between a one-liner and RFC is a must, is this documented somewhere?

A one-liner in user-land multiplied by 10000 applications is 10000 duplicated one-liners which will all additionally suffer from PHP has no function autoloading and user-land functions are slow.

@nikic
Copy link
Member

nikic commented Jun 14, 2018

From experience we know that the $use_keys=true default value of iterator_to_array is a very bad default choice that commonly causes confusion. We might want to consider defaulting it to false here -- on the other hand, that would make the behavior inconsistent with a very similar function.

@krakjoe krakjoe added the RFC label Jun 14, 2018
@krakjoe
Copy link
Member

krakjoe commented Jun 14, 2018

Sorry to be a pain, but we do need a discussion on internals, and an RFC (to follow maybe) ... please get the ball rolling ;)

@Majkl578
Copy link
Contributor Author

RFC declined.

@Majkl578 Majkl578 closed this Jul 17, 2018
@Majkl578 Majkl578 deleted the iterable_to_array branch July 17, 2018 12:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants