On Mon, Feb 11, 2019 at 8:39 AM Woortmann, Enno enno.woortmann@web.de
wrote:
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.
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
--
My position is the same: pushing the variadic behavior into the
functions means that each function needs to pick ||
or &&
behavior, both of which are useful. I would rather see more
descriptive function names, such as all_of
or any_of
:
if (!all_of('is_numeric', [$input['example1'],
$input['example2']])) {/.../}
These do not need to be part of PHP core, but perhaps they could be.
I recognize that there is one downside, which is that lazy evaluation
is lost, but generally don't see it to be an issue in these specific
cases.
Lazy evaluation doesn't have to be lost if the all_of and any_of functions
are written correctly. all_of will return false as soon as one of them
fails, and any_of will return true as soon as one of them passes.
<?php
function all_of($callback,...$params){
foreach($params as $param){
if(!$callback($param)){
return false;
}
}
return true;
}
function any_of($callback,...$params){
foreach($params as $param){
if($callback($param)){
return true;
}
}
return false;
}
Unless you are talking about cases like this:
if(is_numeric(reallyFastFunc($foo)) || is_numeric(reallySlowFunc($bar)))
In that case, you might be able to short circuit the evaluation of
reallySlowFunc($bar), which wouldn't be the case with
if(any_of('is_numeric',reallyFastFunc($foo),reallySlowFunc($bar))){}
However, at that point, I'd say that
1.) If performance isn't an issue, break those function calls out and make
your code more readable:
$f1 = reallyFastFunc($foo);
$f2 = reallySlowFunc($bar);
if(any_of('is_numeric',$f1,$f2)){}
2.) If performance is an issue, fall back to the old method
if(is_numeric(reallyFastFunc($foo)) || is_numeric(reallySlowFunc($bar))){}
--
--
-- Chase
chasepeeler@gmail.com