Welcome! Log In Create A New Profile

Advanced

[PHP-DEV] [RFC][Under Discussion] Add functions array_key_first() and array_key_last()

Posted by Enno Woortmann 
Hello internals,

I've changed the status of the currently introduced RFC to add the
functions array_key_first() and array_key_last() to "Under Discussion".

https://wiki.php.net/rfc/array_key_first_last

Regards,

Enno



--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
On 13.06.2018 at 21:26, Enno Woortmann wrote:

> I've changed the status of the currently introduced RFC to add the
> functions array_key_first() and array_key_last() to "Under Discussion".
>
> https://wiki.php.net/rfc/array_key_first_last

Thanks for working on this, Enno!

I suggest to address Côme's suggestion[1] on this mailing list and
especially in the RFC (the template[2] offers “Open Issues” and
“Rejected Features” sections).

[1] <https://externals.io/message/102225#102232>;

--
Christoph M. Becker

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Hi,

On 13.06.2018 at 23:10, Christoph M. Becker wrote:

> I suggest to address Côme's suggestion[1] on this mailing list and
> especially in the RFC (the template[2] offers “Open Issues” and
> “Rejected Features” sections).
>
> [1] <https://externals.io/message/102225#102232>;
>

I've added the "Open Issues" section to the RFC and added the idea of Côme and Gabriel to add the corresponding functions for handling the values of the outer elements of an array to provide a complete set of functions.
Currently I see three possibilities to handle the idea. Either extend the scope of the RFC to cover also the handling of the values, which could be implemented rather fast and by reusing a lot of code as the current implementation already gathers the bucket for the first/last element of an array, or move this idea to a future scope which should be covered by a separate RFC. The third alternative would be to skip the implementation of the corresponding functions.

In my opinion it's a good idea to complete the function set by also providing functions for the handling of array values. Both opportunities which would lead to the completed set are practicable in my view.

Any opinions concerning this issue?

Good night (or day, wherever you are ;) ),
Enno



--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
On 13/06/18 20:26, Enno Woortmann wrote:
> Hello internals,
>
> I've changed the status of the currently introduced RFC to add the
> functions array_key_first() and array_key_last() to "Under Discussion".
>
> https://wiki.php.net/rfc/array_key_first_last
>
> Regards,
>
> Enno

What is the behaviour if the array does not exist? From the current RFC
it appears it would return null? Wouldn't it be better to return false
for this situation?

Niel

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Hi niel,


On 15.06.2018 at 17:37 niel wrote:
> What is the behaviour if the array does not exist? From the current
> RFC it appears it would return null? Wouldn't it be better to return
> false for this situation?
>

Thanks for the comment. Why do you think false would be a better return
value?

Currently if the given value isn't an array or no parameter is given a
warning will be thrown and null will be returned.
In my opinion null exists to show the absence of a defined value. If one
of the proposed functions is called with a variable which isn't an array
or an empty array (or even a call with no parameter) there is neither a
first nor a last key and thus null is the value which is returned.
Compare the tests for the error cases:
https://github.com/php/php-src/pull/3256/files#diff-e00a584724b997f38e851e15f1e20c39

This behavior is also implemented in existing functions like eg.
array_pop():
https://github.com/php/php-src/blob/master/ext/standard/tests/array/array_pop_errors.phpt

Enno


--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
On 06/15/2018 08:37 AM, niel wrote:
> On 13/06/18 20:26, Enno Woortmann wrote:
>> Hello internals,
>>
>> I've changed the status of the currently introduced RFC to add the
>> functions array_key_first() and array_key_last() to "Under Discussion".
>>
>> https://wiki.php.net/rfc/array_key_first_last
>>
>> Regards,
>>
>> Enno
>
> What is the behaviour if the array does not exist? From the current RFC
> it appears it would return null? Wouldn't it be better to return false
> for this situation?
>

I don't like throwing false when something doesn't exist.

apcu does that - returns false instead of null when a record doesn't
exist, and it is very problematic when the stored value literally is false.

granted a boolean can't be used for an array key, but still, if there
isn't something to return than null is better than a boolean.

boolean is a value, null is the absence of a value, which is more
accurate, no?


--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Hi Alice,


Am 17.06.2018 um 22:16 schrieb Alice Wonder:
> boolean is a value, null is the absence of a value, which is more
> accurate, no?

In my opinion that's the argument to return null for either parameters
which aren't an array or empty arrays simply because a first/last key
isn't present and null is the value to be returned for an undefined state.
I've tested this behavior with other array_* functions which are
provided in the PHP core and they provide null consistently, eg.:

[email protected]:/var/www/WOL-Soft# php -r "var_dump(array_keys(1));"
PHP Warning:  array_keys() expects parameter 1 to be array, integer
given in Command line code on line 1
NULL
[email protected]:/var/www/WOL-Soft# php -r
"var_dump(array_values('hello'));"
PHP Warning:  array_values() expects parameter 1 to be array, string
given in Command line code on line 1
NULL
[email protected]:/var/www/WOL-Soft# php -r "var_dump(array_flip(null));"
PHP Warning:  array_flip() expects parameter 1 to be array, null given
in Command line code on line 1
NULL

There was another remark which wasn't sent to the internals mail list
but to my personal mail account (mehh :( ) which supported to return false:

"because a lot of functions act the way returning false when things go
wrong even when they normally only would return string/int/array which
should be justification enough: consistency"

An example for this argument was the function strpos which may be
checked with === or !== against false.
But the real discussion about the return value and the facility of
comparison against another value is only interesting if we extend the
scope of this RFC to cover also array_value_(first|last), as null as an
array key is not supported and will be casted to an empty string. Due to
this internal handling of array keys, null is for the functions
array_key(first|last) an unique return value to evaluate failures.

My opinion about this subject supports your argument as null is the
value which should be returned if the requested value is not defined. If
a variable which is neither an array nor an array with entries is passed
neither the first/last key nor the first/last value is a defined value
and thus null should be the return value.

Especially if we decide to extend the scope of this RFC to cover also
array_value_(first|last) there is no possibility to provide a return
value which doesn't collide with a possible array value. If cases occur
which may resolve into a collision, the usage of functions like
is_array() and empty()/count() is inevitable as both null and false are
valid values for an array value. To argument with the semantic of false
and null the correct return value should be null for each of the
proposed functions (as well the proposed functions which are currently
covered by the RFC as the extended version which also covers the methody
array_value(first|last) ) as null defines an undefined value.

Regards,
Enno


--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
On 17/06/18 23:09, Enno Woortmann wrote:
> Hi Alice,
>
>
> Am 17.06.2018 um 22:16 schrieb Alice Wonder:
>> boolean is a value, null is the absence of a value, which is more
>> accurate, no?
>
> In my opinion that's the argument to return null for either parameters
> which aren't an array or empty arrays simply because a first/last key
> isn't present and null is the value to be returned for an undefined state.
> I've tested this behavior with other array_* functions which are
> provided in the PHP core and they provide null consistently, eg.:
>
> [email protected]:/var/www/WOL-Soft# php -r "var_dump(array_keys(1));"
> PHP Warning:  array_keys() expects parameter 1 to be array, integer
> given in Command line code on line 1
> NULL
> [email protected]:/var/www/WOL-Soft# php -r
> "var_dump(array_values('hello'));"
> PHP Warning:  array_values() expects parameter 1 to be array, string
> given in Command line code on line 1
> NULL
> [email protected]:/var/www/WOL-Soft# php -r "var_dump(array_flip(null));"
> PHP Warning:  array_flip() expects parameter 1 to be array, null given
> in Command line code on line 1
> NULL
>
> There was another remark which wasn't sent to the internals mail list
> but to my personal mail account (mehh :( ) which supported to return false:
>
> "because a lot of functions act the way returning false when things go
> wrong even when they normally only would return string/int/array which
> should be justification enough: consistency"
>
> An example for this argument was the function strpos which may be
> checked with === or !== against false.
> But the real discussion about the return value and the facility of
> comparison against another value is only interesting if we extend the
> scope of this RFC to cover also array_value_(first|last), as null as an
> array key is not supported and will be casted to an empty string. Due to
> this internal handling of array keys, null is for the functions
> array_key(first|last) an unique return value to evaluate failures.
>
> My opinion about this subject supports your argument as null is the
> value which should be returned if the requested value is not defined. If
> a variable which is neither an array nor an array with entries is passed
> neither the first/last key nor the first/last value is a defined value
> and thus null should be the return value.
>
> Especially if we decide to extend the scope of this RFC to cover also
> array_value_(first|last) there is no possibility to provide a return
> value which doesn't collide with a possible array value. If cases occur
> which may resolve into a collision, the usage of functions like
> is_array() and empty()/count() is inevitable as both null and false are
> valid values for an array value. To argument with the semantic of false
> and null the correct return value should be null for each of the
> proposed functions (as well the proposed functions which are currently
> covered by the RFC as the extended version which also covers the methody
> array_value(first|last) ) as null defines an undefined value.
>
> Regards,
> Enno

Hi, I didn't reply to your question as to why I thought false would be a
better return value for non-array, as I thought Reindl covered my
feelings completely.

Given the points made by Alice and yourself I've reconsidered 'false'
being a better choice than 'null', as it might be a valid return value
from the array.

However my main concern that a non-array variable or a non-existent
value, are an error and need to be handled appropriately, has not
changed. IMO, a notice/warning does little to nothing in helping the
programmer determine the problem and track down the cause. Which leaves
one having to wrap these functions in 'if (is_array($var) &&
!empty($var)) {...}' to prevent the possibility.

Niel

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Hi niel,

Am 18.06.2018 um 01:59 schrieb niel:
> However my main concern that a non-array variable or a non-existent
> value, are an error and need to be handled appropriately, has not
> changed. IMO, a notice/warning does little to nothing in helping the
> programmer determine the problem and track down the cause. Which
> leaves one having to wrap these functions in 'if (is_array($var) &&
> !empty($var)) {...}' to prevent the possibility.

The current implementation is eqivalent to the other array_* functions
as shown in the previous mail and can be checked in
https://github.com/php/php-src/pull/3256/commits/ec2332be93272d202a2a5cef841c266f77f64b08#diff-e00a584724b997f38e851e15f1e20c39

I can comprehend your doubts about the return value but currently I
can't imagine a solution which would suite the case better than null
especially if we think about extending the scope to
array_value_(first|last).
Do you/anyone have an idea how we can provide better information towards
the programmer to determine the issue?

Enno


--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
On 18.06.2018 at 00:09, Enno Woortmann wrote:

> In my opinion that's the argument to return null for either parameters
> which aren't an array or empty arrays simply because a first/last key
> isn't present and null is the value to be returned for an undefined state.
> I've tested this behavior with other array_* functions which are
> provided in the PHP core and they provide null consistently, eg.:
>
> [email protected]:/var/www/WOL-Soft# php -r "var_dump(array_keys(1));"
> PHP Warning:  array_keys() expects parameter 1 to be array, integer
> given in Command line code on line 1
> NULL
> [email protected]:/var/www/WOL-Soft# php -r
> "var_dump(array_values('hello'));"
> PHP Warning:  array_values() expects parameter 1 to be array, string
> given in Command line code on line 1
> NULL
> [email protected]:/var/www/WOL-Soft# php -r "var_dump(array_flip(null));"
> PHP Warning:  array_flip() expects parameter 1 to be array, null given
> in Command line code on line 1
> NULL

These return values are due to zend_parse_parameters() failures (i.e.
the given types don't match the expected types), and it's customary to
return NULL in this case (under strict typing an exception would be
thrown instead). However, most functions signal other failures by
returning FALSE, for instance:

var_dump(array_search('foo', [])); // => bool(false)

I would prefer, if these other functions would return NULL, though, but
we can't change that for BC reasons.

--
Christoph M. Becker

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
On Monday, June 18, 2018 4:25:27 AM CDT Christoph M. Becker wrote:
> On 18.06.2018 at 00:09, Enno Woortmann wrote:
> > In my opinion that's the argument to return null for either parameters
> > which aren't an array or empty arrays simply because a first/last key
> > isn't present and null is the value to be returned for an undefined state.
> > I've tested this behavior with other array_* functions which are
> > provided in the PHP core and they provide null consistently, eg.:
> >
> > [email protected]:/var/www/WOL-Soft# php -r "var_dump(array_keys(1));"
> > PHP Warning: array_keys() expects parameter 1 to be array, integer
> > given in Command line code on line 1
> > NULL
> > [email protected]:/var/www/WOL-Soft# php -r
> > "var_dump(array_values('hello'));"
> > PHP Warning: array_values() expects parameter 1 to be array, string
> > given in Command line code on line 1
> > NULL
> > [email protected]:/var/www/WOL-Soft# php -r
> > "var_dump(array_flip(null));"
> > PHP Warning: array_flip() expects parameter 1 to be array, null given
> > in Command line code on line 1
> > NULL
>
> These return values are due to zend_parse_parameters() failures (i.e.
> the given types don't match the expected types), and it's customary to
> return NULL in this case (under strict typing an exception would be
> thrown instead). However, most functions signal other failures by
> returning FALSE, for instance:
>
> var_dump(array_search('foo', [])); // => bool(false)
>
> I would prefer, if these other functions would return NULL, though, but
> we can't change that for BC reasons.

Returning false for "not found" rather than "null" is a big middle-finger to
users. :-) Besides the reasons here, the violation of type constraints
totally screws up the surrounding code. Especially with null-coalesce. For
instance, this thing of beauty:

$secret = getenv('APP_SECRET')
?? $_SERVER['APP_SECRET']
?? getenv('DEFAULT_SECRET')
;

doesn't actually work, because getenv() returns false instead of null.
Instead you have to do this mess:

$secret = (getenv('APP_SECRET') ?: null)
?? $_SERVER['APP_SECRET']
?? (getenv('DEFAULT_SECRET') ?: null)
;

See also:

https://www.garfieldtech.com/blog/empty-return-values

Can we please never return false for error/not-found, ever, period, forever
more? It's a fundamentally broken idiom that needs to die.

--Larry Garfield
On 18.06.2018 at 17:32, Larry Garfield wrote:

> Can we please never return false for error/not-found, ever, period, forever
> more? It's a fundamentally broken idiom that needs to die.

“But wait!” some cry. “What about consistency with existing functions?”

--
Christoph M. Becker

--
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