[PHP-DEV] Variadic is_*() functions

2019-02-11 Thread Woortmann, Enno

Hi internals,

as I reviewed a bunch of code for handling data from different sources
(eg. json) in the last days I stumbled over code like this multiple times:


if (!(is_numeric($input['example1']) && is_numeric($input['example2']))) {


if (!is_numeric($input['example1'] || !is_numeric($input['example2'])) {


and I had multiple problems with this.

* it's kinda hard to read

* multiple writings for the same logic

* ends up in complex conditionals


I searched for discussions regarding this topic and found it was
mentioned in a 'side thread' of the RFC for changing empty() to a
variadic a few years ago (https://externals.io/message/82549#82641) and
I'd like to collect some feedback if it's wothy to revisit the topic to
write the above example as:


if (!is_numeric($input['example1'], $input['example2'])) {


Except the is_callable() method all is_*() methods could be extended
with a variadic behaviour which would check the given values from the
left to the right and abort if a value doesn't match the condition (in
the example if a given value is not numeric). So all in all there are
some points to talk about: Revisit the discussion? Which functions are
reasonable to be extended? If all functions are reasonable: what to do
with is_callable()?

regards,
Enno

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



Re: [PHP-DEV] Re:[PHP-DEV] [VOTE] array_key_first(),array_key_last(), array_value_first(),array_value_last()

2018-07-11 Thread Woortmann, Enno

Am 11.07.2018 um 18:20 schrieb Levi Morrison:


As an example, it was claimed:


If I use a function I expect it to give me a return value which I can
use without any further post processing $wantedValue =
fancyFunction($someInput);

But this isn't true even for the array_value_* functions. There must
be pre or post processing because of error conditions. This was
pointed out by myself and others, but it was still ignored.

This is what I mean by discarded, not discussed.


In my eyes being aware of what I put into a function and thus catching 
non array inputs and empty inputs before differs a lot from post 
processing return values as it increases the comprehensibility of the 
code. I also can think of cases where the input format is known and no 
further checks are required.


Additionally the tuple return pattern is not common among the PHP core 
functions and I don't know many occurences of this pattern in userland 
PHP code neither at the companies I've worked at nor at open source 
software/frameworks (correct me if I'm wrong) except the by far outdated 
old foreach construct with reset() and each(), thus I assume it's not a 
that common pattern for PHP developers to use it in core functions.


As I pointed out during the discussion we should also watch at existing 
functions with the same problem, differ between a valid return value and 
an error.
Not all of them can be changed to use different return mechanisms like 
the tuple return pattern (eg. array_pop).


Maybe we can instead think about changing Z_PARAM_ARRAY_EX in a later 
stage to not return null in error cases but instead throw an 
InvalidArgumentException or something like that (at least for function 
calls with an empty array for functions which require a filled array, 
for invalid types maybe a fatal TypeError like it's thrown when a type 
hinted argument in a userland function is violated is the correct 
choice). Would be a pretty large BC breaking change but it would be 
consistent among the array functions.


In my opinion neither rejecting the RFC nor changing it to return tuples 
solves the underlying problem.


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



[PHP-DEV] [VOTE] array_key_first(), array_key_last(), array_value_first(), array_value_last()

2018-07-09 Thread Woortmann, Enno

Hi,

as the discussion got no new contributions I'd like to start the voting 
for the RFC fo add new functions for the handling of outer array elements.


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

To have a better separation I split up the vote for the functions. The 
first vote covers the functions to handle keys: array_key_first() and 
array_key_last(). The second vote covers the corresponding functions to 
handle the values: array_value_first() and array_value_last().


As this RFC adds functions but doesn't change the language syntax a 50% 
+ 1 majority is required for both votes. The votes are open until 
2018-07-16.


The discussion for this RFC is located at

https://externals.io/message/102245

Regards,

Enno




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



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

2018-06-28 Thread Woortmann, Enno

Am 26.06.2018 um 16:42 schrieb Rowan Collins:

On 26 June 2018 at 08:58, Marc Bennewitz  wrote:


Hi all,

I just want to add some information that I feel it's missing in that
discussion - I'm sorry if it was mentioned already.

1. It's already possible to extract the key and value of any index
position of an array using array_slice: https://3v4l.org/mib99

2. "array_[key|value]_[first|last]($array)" is in my opinion not a good
option as it lacks the possibility to extract key/value from any position.
Something like "array_[key|value]_index($array, $index)" where $index
would be the index position or negative index position from right.


The big advantage of separate functions is that they make the intent clear;
we could combine all four functions into one: array_index(int $position,
bool $key), but "array_key_last($something)" is a lot clearer to read than
"array_index($something, -1, true)". Are there actually use cases for
getting "the 5th key from the end of the array", common enough to make "the
last key in the array" harder to write?

Regards,


As well as Rowan I don't see use cases for fetching keys/values at any 
position inside the array for justifying to break up the current 
readable function signatures.
Combining multiple use cases and tasks into a single function always 
offends the single responsibility principle (compare my previous mail) 
and thus should be avoided.


Are there other opinions concerning this topic?
I'd like to finish the discussion soon and move on to the voting phase.

Regards,
Enno

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



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

2018-06-28 Thread Woortmann, Enno

Hi David,


thanks for your brainstorming suggestions. My opinion on the options:


1. Keys being stored as reference:

$valueOutput = array_first(array $array, ?string &$keyOutput = null);
In my opinion using references to return additional values from a 
function is quiet hacky. I think returning a single value leads to 
significantly clearer code and thus supports the developer.

2. Function will returns value or key, by option (similar to
array_filter()):
​​
array_first(array $array, int $options = ARRAY_VALUE);
​
array_first(array $array, int $options = ARRAY_KEY); ​
This violates the single responsibility principle and consequently isn't 
a good move

​3. ​
F
​unction will returns value or key, by boolean argument:

array_first(array $array, bool $returnKeyInsteadOfValue = false);
array_first(array $array, bool $returnKeyInsteadOfValue = true); ​

Compare 2.

4. Specific method to return key instead of value:

array_first(array $array);
array_first_key(array $array);
This is the RFC just with slightly different function names. I think 
using array_key_first and array_value_first (and the corresponding 
functions for the last array element) provides a consistent naming.

5. Consider that keys could be obtained via array_keys(), so array_first()
should just care about values:

array_first(array_keys($array));
This solution requires a copy of the array (keys) which extends the time 
complexity and the memory usage of the task.


Regards,
Enno


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

2018-06-20 Thread Woortmann, Enno

Am 20.06.2018 um 15:55 schrieb Levi Morrison:

Your wish cannot be granted for `array_value_last` and
`array_value_first`; you cannot know by itself if there is a failure
condition.


I can comprehend your issue with the lack of distinctness between the 
error case and the 'real' array value null without further checks.
But in my opinion the required additional checking of the $input is a 
learned behaviour from existing functions which handle single value 
elements from an array as reset(), current() and end() will return false 
for empty arrays or null for invalid data types which are both also 
valid element values.
array_pop() and array_shift() also behave in a comparable way as they 
return null as well for empty arrays as for non array input.

This is not "clean". In contrast here is with my proposal:

 if ([$key, $value] = array_last($input) {
 // do something
 }
I still think that this proposed syntax is unintuitive and hard to 
comprehend for the user of the function.
I don't think many PHP developers out there know that the condition 
inside the if will evaluate to null if array_last returns null.


Additionally I don't know about any other function where a construct 
like this has to be used to extract two or more different semantic 
entities, in this case the key and the value, out of a PHP core function 
return value.


Enno

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



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

2018-06-20 Thread Woortmann, Enno

Hi Levi,


Am 20.06.2018 um 04:47 schrieb Levi Morrison:

 list($key, $value) = array_first($input);
 // $key will be null if the call failed

 list($key, $value) = array_last($input);
 // $key will be null if the call failed


Your proposed functions would be implementable with the internal 
functions but I think this approach doesn't provide a clean function 
interface as it forces the user to evaluate the wanted value from the 
returned array structure by using either the list() construct or 
something like $key = array_first($input)[0];


I believe two functions with this interface will be confusing and less 
intuitive for the developer.
If I use a function I expect it to give me a return value which I can 
use without any further post processing $wantedValue = 
fancyFunction($someInput);


Enno

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



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

2018-06-19 Thread Woortmann, Enno

Hello internals,
On 15.06.2018 at 00:37, Enno Woortmann wrote:
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.


I've extended the scope of the RFC to cover additionally the functions 
array_value_first($array) and array_value_last($array).
The updated RFC is still available at 
https://wiki.php.net/rfc/array_key_first_last 

I've added a commit to the pull request located at 
https://github.com/php/php-src/pull/3256 
 to 
add the implementation and the tests for the extended scope.

Regards,
Enno