Welcome! Log In Create A New Profile

Advanced

[PHP-DEV][RFC][DISCUSSION] Collection Inspection

Posted by Michael Morris 
Michael Morris
Re: [PHP-DEV][RFC][DISCUSSION] Collection Inspection
January 30, 2018 01:50AM
On Mon, Jan 29, 2018 at 6:16 PM, Larry Garfield <[email protected]>
wrote:
>
>
> Really, these functions would be useful only on arrays, period. To allow
> them
> on anything else is just dangerous, and on other iterables there are
> better,
> more robust approaches (as discussed elsewhere in this thread).
>
> As you've demonstrated they're also quite compact and effective to do in
> user-
> space, so unless there's a massive performance difference of moving them
> to C
> they don't seem all that appropriate to add to the language directly.
>
> --Larry Garfield
>

Didn't you personally raise the issue of hard dependencies doing this sort
of functionality creates? Implementable in userland or not, this is pretty
low level functionality.

Hmm.. If limited to arrays only then array_filter with count is pretty
close to what we want.

assert(count(array_filter($a, is_string)) === count($a));

That's not optimal though - granted assert code doesn't *have* to be
optimal, but that's still a wordy construction.

So what about this function

bool array_test(array $array [, callable $callback [, mixed $flag = 0]])

Iterates over $array, passing the value of each element to $callback. If
the callback returns true for all elements the array_test returns true,
otherwise it returns false. It is not guaranteed to iterate over the entire
array - it stops when the first false result is returned by the callback.
Flags are the same as array_filter.

So...
assert( array_test($a, 'is_string'), TypeError);
assert( array_test($a, function($v) { return $v instanceof SomeClass; }),
TypeError);


Not what I came into the thread looking for, but it's not bad.

s
Christoph M. Becker
Re: [PHP-DEV][RFC][DISCUSSION] Collection Inspection
January 30, 2018 01:10PM
On 30.01.2018 at 01:46, Michael Morris wrote:

> So what about this function
>
> bool array_test(array $array [, callable $callback [, mixed $flag = 0]])
>
> Iterates over $array, passing the value of each element to $callback. If
> the callback returns true for all elements the array_test returns true,
> otherwise it returns false. It is not guaranteed to iterate over the entire
> array - it stops when the first false result is returned by the callback.
> Flags are the same as array_filter.
>
> So...
> assert( array_test($a, 'is_string'), TypeError);
> assert( array_test($a, function($v) { return $v instanceof SomeClass; }),
> TypeError);
>
>
> Not what I came into the thread looking for, but it's not bad.

See https://github.com/php/php-src/pull/1385 which apparently has been
abandoned, unfortunately.

--
Christoph M. Becker

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Larry Garfield
Re: [PHP-DEV][RFC][DISCUSSION] Collection Inspection
January 30, 2018 07:20PM
On Monday, January 29, 2018 6:46:10 PM CST Michael Morris wrote:
> On Mon, Jan 29, 2018 at 6:16 PM, Larry Garfield <[email protected]>
>
> wrote:
> > Really, these functions would be useful only on arrays, period. To allow
> > them
> > on anything else is just dangerous, and on other iterables there are
> > better,
> > more robust approaches (as discussed elsewhere in this thread).
> >
> > As you've demonstrated they're also quite compact and effective to do in
> > user-
> > space, so unless there's a massive performance difference of moving them
> > to C
> > they don't seem all that appropriate to add to the language directly.
> >
> > --Larry Garfield
>
> Didn't you personally raise the issue of hard dependencies doing this sort
> of functionality creates? Implementable in userland or not, this is pretty
> low level functionality.

I don't recall doing so in this thread, but I most likely have on some other
issue. It's the sort of comment that I would make. :-)

However, that's for a very commonly used function where just inlining it is
prohibitive. As you've demonstrated below, this functionality is easily a one
liner, and it's a one-liner in an assert statement most likely.

> Hmm.. If limited to arrays only then array_filter with count is pretty
> close to what we want.
>
> assert(count(array_filter($a, is_string)) === count($a));
>
> That's not optimal though - granted assert code doesn't *have* to be
> optimal, but that's still a wordy construction.

Personally I think that's fine, and doesn't need a language-level utility
function to wrap it any further.

(Yes, that's a subjective metric. So are most statements about what
should[n't] be included in the language itself. Others are welcome to
disagree, but this falls below my threshold of necessity.)

--Larry Garfield
Michael Morris
Re: [PHP-DEV][RFC][DISCUSSION] Collection Inspection
January 30, 2018 08:10PM
On Tue, Jan 30, 2018 at 12:13 PM, Larry Garfield <[email protected]>
wrote:

> On Monday, January 29, 2018 6:46:10 PM CST Michael Morris wrote:
> > On Mon, Jan 29, 2018 at 6:16 PM, Larry Garfield <[email protected]>
> >
> > wrote:
> > > Really, these functions would be useful only on arrays, period. To
> allow
> > > them
> > > on anything else is just dangerous, and on other iterables there are
> > > better,
> > > more robust approaches (as discussed elsewhere in this thread).
> > >
> > > As you've demonstrated they're also quite compact and effective to do
> in
> > > user-
> > > space, so unless there's a massive performance difference of moving
> them
> > > to C
> > > they don't seem all that appropriate to add to the language directly.
> > >
> > > --Larry Garfield
> >
> > Didn't you personally raise the issue of hard dependencies doing this
> sort
> > of functionality creates? Implementable in userland or not, this is
> pretty
> > low level functionality.
>
> I don't recall doing so in this thread, but I most likely have on some
> other
> issue. It's the sort of comment that I would make. :-)
>

It was during the discussion on the Drupal list on adding runtime
assertions, the Inspector class in general. Curiously, no one on that list
raised the problem of allowing Inspector to traverse any Traversable. At
the time Drupal was PHP 5.4 min, so no generators to consider, and I guess
the other implications skipped everyone's mind.

Personally I think that's fine, and doesn't need a language-level utility
> function to wrap it any further.
>
>
We'll just have to disagree then. After all, roughly half the array_*
functions can be user implemented, as can roughly half the string functions
(though how to do so is often cryptic to beginners).

array_test might not be the best name. Anyone got alternatives other than
the one in the abandoned RFC mentioned elsewhere in this thread (Not that
that one is bad, but if this is the direction to go some input on what to
actually call the thing would be nice.)?
Levi Morrison
Re: [PHP-DEV][RFC][DISCUSSION] Collection Inspection
January 30, 2018 09:30PM
On Tue, Jan 30, 2018 at 11:13 AM, Larry Garfield <[email protected]> wrote:
> On Monday, January 29, 2018 6:46:10 PM CST Michael Morris wrote:
>> On Mon, Jan 29, 2018 at 6:16 PM, Larry Garfield <[email protected]>
>>
>> wrote:
>> > Really, these functions would be useful only on arrays, period. To allow
>> > them
>> > on anything else is just dangerous, and on other iterables there are
>> > better,
>> > more robust approaches (as discussed elsewhere in this thread).
>> >
>> > As you've demonstrated they're also quite compact and effective to do in
>> > user-
>> > space, so unless there's a massive performance difference of moving them
>> > to C
>> > they don't seem all that appropriate to add to the language directly.
>> >
>> > --Larry Garfield
>>
>> Didn't you personally raise the issue of hard dependencies doing this sort
>> of functionality creates? Implementable in userland or not, this is pretty
>> low level functionality.
>
> I don't recall doing so in this thread, but I most likely have on some other
> issue. It's the sort of comment that I would make. :-)
>
> However, that's for a very commonly used function where just inlining it is
> prohibitive. As you've demonstrated below, this functionality is easily a one
> liner, and it's a one-liner in an assert statement most likely.
>
>> Hmm.. If limited to arrays only then array_filter with count is pretty
>> close to what we want.
>>
>> assert(count(array_filter($a, is_string)) === count($a));
>>
>> That's not optimal though - granted assert code doesn't *have* to be
>> optimal, but that's still a wordy construction.
>
> Personally I think that's fine, and doesn't need a language-level utility
> function to wrap it any further.
>
> (Yes, that's a subjective metric. So are most statements about what
> should[n't] be included in the language itself. Others are welcome to
> disagree, but this falls below my threshold of necessity.)
>
> --Larry Garfield


I agree with this sentiment from Larry. However I do think there is a
function we could add:

function every(callable $predicate, traversable $input): bool {
foreach ($input as $value) {
if (!$predicate($value)) {
return false;
}
}
return true;
}

In which case the code would become:

assert(every('is_string', $input));

Of course, when passing a traversable the caller must to be careful as
it will be consumed. If they don't want that to happen they can
convert it to an array (possibly with iterator_to_array).

The reason this "every" function is better than "array_test" is
because it is more general and works with more things than just types.
The name "every" I borrowed from Clojure, but it's known by many
names; in Java it is known as "allMatch".

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Michael Morris
Re: [PHP-DEV][RFC][DISCUSSION] Collection Inspection
February 06, 2018 09:20PM
On Tue, Jan 30, 2018 at 2:24 PM, Levi Morrison <[email protected]> wrote:

> On Tue, Jan 30, 2018 at 11:13 AM, Larry Garfield <[email protected]>
> wrote:
> > On Monday, January 29, 2018 6:46:10 PM CST Michael Morris wrote:
> >> On Mon, Jan 29, 2018 at 6:16 PM, Larry Garfield <[email protected]
> >
> >>
> >> wrote:
> >> > Really, these functions would be useful only on arrays, period. To
> allow
> >> > them
> >> > on anything else is just dangerous, and on other iterables there are
> >> > better,
> >> > more robust approaches (as discussed elsewhere in this thread).
> >> >
> >> > As you've demonstrated they're also quite compact and effective to do
> in
> >> > user-
> >> > space, so unless there's a massive performance difference of moving
> them
> >> > to C
> >> > they don't seem all that appropriate to add to the language directly.
> >> >
> >> > --Larry Garfield
> >>
> >> Didn't you personally raise the issue of hard dependencies doing this
> sort
> >> of functionality creates? Implementable in userland or not, this is
> pretty
> >> low level functionality.
> >
> > I don't recall doing so in this thread, but I most likely have on some
> other
> > issue. It's the sort of comment that I would make. :-)
> >
> > However, that's for a very commonly used function where just inlining it
> is
> > prohibitive. As you've demonstrated below, this functionality is easily
> a one
> > liner, and it's a one-liner in an assert statement most likely.
> >
> >> Hmm.. If limited to arrays only then array_filter with count is pretty
> >> close to what we want.
> >>
> >> assert(count(array_filter($a, is_string)) === count($a));
> >>
> >> That's not optimal though - granted assert code doesn't *have* to be
> >> optimal, but that's still a wordy construction.
> >
> > Personally I think that's fine, and doesn't need a language-level utility
> > function to wrap it any further.
> >
> > (Yes, that's a subjective metric. So are most statements about what
> > should[n't] be included in the language itself. Others are welcome to
> > disagree, but this falls below my threshold of necessity.)
> >
> > --Larry Garfield
>
>
> I agree with this sentiment from Larry. However I do think there is a
> function we could add:
>
> function every(callable $predicate, traversable $input): bool {
> foreach ($input as $value) {
> if (!$predicate($value)) {
> return false;
> }
> }
> return true;
> }
>
> In which case the code would become:
>
> assert(every('is_string', $input));
>
> Of course, when passing a traversable the caller must to be careful as
> it will be consumed. If they don't want that to happen they can
> convert it to an array (possibly with iterator_to_array).
>
> The reason this "every" function is better than "array_test" is
> because it is more general and works with more things than just types.
> The name "every" I borrowed from Clojure, but it's known by many
> names; in Java it is known as "allMatch".
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
>
>
I'm fine with this - I just want the inspector to be part of the language
so that a hidden dependency isn't required.
Rowan Collins
Re: [PHP-DEV][RFC][DISCUSSION] Collection Inspection
February 06, 2018 10:00PM
On 6 February 2018 20:18:07 GMT+00:00, Michael Morris <[email protected]> wrote:
>I'm fine with this - I just want the inspector to be part of the
>language
>so that a hidden dependency isn't required.

I may be being dumb, but I don't get why you keep referring to this as a "hidden dependency". It's a dependency, for sure, but why is it any more "hidden" than any other utility library?

Regards,

--
Rowan Collins
[IMSoP]

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Michael Morris
Re: [PHP-DEV][RFC][DISCUSSION] Collection Inspection
February 06, 2018 10:20PM
The Dependency injector isn't aware of the reference and is unable to
modify it in any way. I've been taught to avoid such dependencies, and to
avoid utility libraries which create such dependencies.

On Tue, Feb 6, 2018 at 2:54 PM, Rowan Collins <[email protected]>
wrote:

> On 6 February 2018 20:18:07 GMT+00:00, Michael Morris <[email protected]>
> wrote:
> >I'm fine with this - I just want the inspector to be part of the
> >language
> >so that a hidden dependency isn't required.
>
> I may be being dumb, but I don't get why you keep referring to this as a
> "hidden dependency". It's a dependency, for sure, but why is it any more
> "hidden" than any other utility library?
>
> Regards,
>
> --
> Rowan Collins
> [IMSoP]
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
>
>
Rowan Collins
Re: [PHP-DEV][RFC][DISCUSSION] Collection Inspection
February 06, 2018 10:30PM
On 6 February 2018 21:10:54 GMT+00:00, Michael Morris <[email protected]> wrote:
>On Tue, Feb 6, 2018 at 2:54 PM, Rowan Collins <[email protected]>
>wrote:
>> I may be being dumb, but I don't get why you keep referring to this
>as a
>> "hidden dependency". It's a dependency, for sure, but why is it any
>more
>> "hidden" than any other utility library?

>The Dependency injector isn't aware of the reference and is unable to
>modify it in any way. I've been taught to avoid such dependencies, and
>to
>avoid utility libraries which create such dependencies.

OK, I see what you mean. But surely it doesn't really have much relevance here, because a function or operator from the language's standard library is just as invisible to dependency injection. In a sense, it's still a utility library, just one that comes bundled with the language rather than installed separately.

Indeed, a built-in function is even more restricted in what you can do with it than a userland one - for instance, you could replace the userland implementation simply by declaring your version first and not including the original, but you can't overwrite a built-in function without hacking into the engine.

I'm not saying this undermines the proposal for adding some extra array functions or operators, but dependency injection and modification are certainly not advantages of doing so.

Regards,

--
Rowan Collins
[IMSoP]

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Sorry, only registered users may post in this forum.

Click here to login