Hi internals,
I created an RFC and put it in discussion status.
https://wiki.php.net/rfc/add_bcdivmod_to_bcmath
I expect return values will probably be the main topic of discussion.
Regards,
Saki
Hi internals,
I created an RFC and put it in discussion status.
https://wiki.php.net/rfc/add_bcdivmod_to_bcmathI expect return values will probably be the main topic of discussion.
Regards,
Saki
Just a suggestion: what about making the returned array an associative
array ? Like so:
array(
'quotient' => 61,
'remainder' => 1,
);
This would remove the need for devs to remember the order of the return
values and would make the return value self-documenting.
Hi
Just a suggestion: what about making the returned array an associative
array ? Like so:array( 'quotient' => 61, 'remainder' => 1, );
This would remove the need for devs to remember the order of the return
values and would make the return value self-documenting.
An associative array would combine the worst of an array (no IDE
autocompletion, no strong typing, increased memory usage) with the worst
of an object (no easy way to extract the values into local variables
with array destructuring).
The example in the RFC doesn't show it, but the following makes the
proposed API really convenient to use:
$slicesOfPizza = new BcMath\Number(8);
$mouthsToFeed = new BcMath\Number(3);
[$perMouth, $slicesLeft] = $slicesOfPizza->divmod($mouthsToFeed);
Note how the order of values matches the words in the method name. First
the result of 'div', then the result of 'mod'.
Best regards
Tim Düsterhus
Hi internals,
I created an RFC and put it in discussion status.
https://wiki.php.net/rfc/add_bcdivmod_to_bcmathI expect return values will probably be the main topic of discussion.
Regards,
Saki
Just a suggestion: what about making the returned array an associative array ? Like so:
array( 'quotient' => 61, 'remainder' => 1, );
This would remove the need for devs to remember the order of the return values and would make the return value self-documenting.
I came here to say the same thing. The best solution would be not having to refer to documentation or experiment with values, and this hits the nail on the head.
The only thing that makes it weird is having to write it out, which at that point, it is probably faster to type out bcdiv and bcmod separately.
Have you considered simply using references passed to the function? I feel like that is more idiomatically php.
— Rob
Hi,
Just a suggestion: what about making the returned array an associative
array ? Like so:array( 'quotient' => 61, 'remainder' => 1, );
This would remove the need for devs to remember the order of the return
values and would make the return value self-documenting.An associative array would combine the worst of an array (no IDE autocompletion, no strong typing, increased memory usage) with the worst of an object (no easy way to extract the values into local variables with array destructuring).
The example in the RFC doesn't show it, but the following makes the proposed API really convenient to use:
$slicesOfPizza = new BcMath\Number(8);
$mouthsToFeed = new BcMath\Number(3);
[$perMouth, $slicesLeft] = $slicesOfPizza->divmod($mouthsToFeed);Note how the order of values matches the words in the method name. First the result of 'div', then the result of 'mod’.
Thanks, I have added this example to the RFC (Please let me know if you have any problems).
I came here to say the same thing. The best solution would be not having to refer to documentation or experiment with values, and this hits the nail on the head.
The only thing that makes it weird is having to write it out, which at that point, it is probably faster to type out bcdiv and bcmod separately.
Have you considered simply using references passed to the function? I feel like that is more idiomatically php.
Of course, that idea was proposed, but it was pointed out that current PHP tends to avoid such implementations, so we didn't adopt it. The reason why passing by reference was not adopted was added to the RFC.
Regards,
Saki
Hi,
Just a suggestion: what about making the returned array an associative
array ? Like so:array( 'quotient' => 61, 'remainder' => 1, );
This would remove the need for devs to remember the order of the return
values and would make the return value self-documenting.An associative array would combine the worst of an array (no IDE autocompletion, no strong typing, increased memory usage) with the worst of an object (no easy way to extract the values into local variables with array destructuring).
The example in the RFC doesn't show it, but the following makes the proposed API really convenient to use:
$slicesOfPizza = new BcMath\Number(8);
$mouthsToFeed = new BcMath\Number(3);
[$perMouth, $slicesLeft] = $slicesOfPizza->divmod($mouthsToFeed);Note how the order of values matches the words in the method name. First the result of 'div', then the result of 'mod’.
Thanks, I have added this example to the RFC (Please let me know if you have any problems).
I came here to say the same thing. The best solution would be not having to refer to documentation or experiment with values, and this hits the nail on the head.
The only thing that makes it weird is having to write it out, which at that point, it is probably faster to type out bcdiv and bcmod separately.
Have you considered simply using references passed to the function? I feel like that is more idiomatically php.
Of course, that idea was proposed, but it was pointed out that current PHP tends to avoid such implementations, so we didn't adopt it. The reason why passing by reference was not adopted was added to the RFC.
Regards,
Saki
I guess it could go either way:
returns by structured array examples:
-
getimagesize()
-
parse_url()
-
pathinfo()
-
stat()
-
posix_getpwuid()
and then these by reference:
- list() -- kinda
-
array_shift()
,array_pop()
, etc. - preg_match*()
- all the sorts
Just thinking through it, return by reference is much more common in PHP than returning structured arrays, and the ones that do make a ton of sense that they do (lots of data).
— Rob
Hi
- list() -- kinda
That is not a function.
array_shift()
,array_pop()
, etc.
These do not return by out-parameter. These return the value and modify
the array by reference to remove the returned value.
- preg_match*()
These only return supplementary data by an out-parameter. The main
result ("does the RFC match") is returned regularly.
- all the sorts
These do not return anything, they modify the array in-place, which is
something different than returning something.
Best regards
Tim Düsterhus
Hi
- list() -- kinda
That is not a function.
array_shift()
,array_pop()
, etc.These do not return by out-parameter. These return the value and modify
the array by reference to remove the returned value.
- preg_match*()
These only return supplementary data by an out-parameter. The main
result ("does the RFC match") is returned regularly.
- all the sorts
These do not return anything, they modify the array in-place, which is
something different than returning something.Best regards
Tim Düsterhus
We can argue the semantics of input/output, but the point still stands that return by reference is still more common than structured array, and even then, those are usually much bigger things.
— Rob
Hi
We can argue the semantics of input/output, but the point still stands that return by reference is still more common than structured array, and even then, those are usually much bigger things.
Happy to argue with you. I explained for each of the examples you
mentioned how it differs from the use-case solved by bcdivmod()
.
To give some examples of functions that return a structured array and
that I believe to be reasonably similar (meaning: they destruct/parse
the input value instead of just providing some metadata like
opcache_get_status()
):
-
pathinfo()
-
date_parse()
-
getimagesize()
-
openssl_x509_parse()
-
password_get_info()
And for functions that return system information:
-
opcache_get_status()
-
sys_getloadavg()
-
stat()
Please explain how their output arrays being “much bigger” makes a
difference to how the API is perceived by the user that wants to use it.
Functions I see where the result is returned by out parameters only,
without having a regular primary return value are (this also includes
some closely related functions in openssl and socket that I do not list
explicitly):
-
getmxrr()
-
openssl_csr_export()
-
socket_getpeername()
And for all of those it would arguably a better API to just return the
value and throw an Exception on failure.
Best regards
Tim Düsterhus
Hi,
Just a suggestion: what about making the returned array an associative
array ? Like so:array( 'quotient' => 61, 'remainder' => 1, );
This would remove the need for devs to remember the order of the return
values and would make the return value self-documenting.An associative array would combine the worst of an array (no IDE autocompletion, no strong typing, increased memory usage) with the worst of an object (no easy way to extract the values into local variables with array destructuring).
The example in the RFC doesn't show it, but the following makes the proposed API really convenient to use:
$slicesOfPizza = new BcMath\Number(8);
$mouthsToFeed = new BcMath\Number(3);
[$perMouth, $slicesLeft] = $slicesOfPizza->divmod($mouthsToFeed);Note how the order of values matches the words in the method name. First the result of 'div', then the result of 'mod’.
Thanks, I have added this example to the RFC (Please let me know if you
have any problems).I came here to say the same thing. The best solution would be not having to refer to documentation or experiment with values, and this hits the nail on the head.
The only thing that makes it weird is having to write it out, which at that point, it is probably faster to type out bcdiv and bcmod separately.
Have you considered simply using references passed to the function? I feel like that is more idiomatically php.
Of course, that idea was proposed, but it was pointed out that current
PHP tends to avoid such implementations, so we didn't adopt it. The
reason why passing by reference was not adopted was added to the RFC.Regards,
Saki
I agree an associative array is the second-worst option. An inout by-ref argument is the absolute worst.
Normally my default position is that when in doubt, make it a structured object with properly defined properties, and screw whatever micro-performance hit it is, you won't notice. 99% of the time I believe that is the correct approach.
I can see the argument that this is the other 1%, since it's just two values, which will basically always be wanted separately but both wanted (meaning divmod(...)->divsor is kinda pointless), and their order should be fairly self-evident.
However, in that case I would urge that both the RFC and the resulting documentation always use examples that return into a [$foo, $bar]
destructured list. Don't even suggest that people should use 0 and 1 indexes. It's a tuple for deconstruction, that's it, if you're using it some other way you're probably wrong. Politely ignore that it's even possible, lest we lead people down the dark path.
(Which means removing the current index-using example and just keeping the pizza example.)
--Larry Garfield
Hi Larry,
I agree an associative array is the second-worst option. An inout by-ref argument is the absolute worst.
Normally my default position is that when in doubt, make it a structured object with properly defined properties, and screw whatever micro-performance hit it is, you won't notice. 99% of the time I believe that is the correct approach.
I can see the argument that this is the other 1%, since it's just two values, which will basically always be wanted separately but both wanted (meaning divmod(...)->divsor is kinda pointless), and their order should be fairly self-evident.
However, in that case I would urge that both the RFC and the resulting documentation always use examples that return into a
[$foo, $bar]
destructured list. Don't even suggest that people should use 0 and 1 indexes. It's a tuple for deconstruction, that's it, if you're using it some other way you're probably wrong. Politely ignore that it's even possible, lest we lead people down the dark path.(Which means removing the current index-using example and just keeping the pizza example.)
--Larry Garfield
Thanks, agree. I rewrote the non-pizza example.
Regards,
Saki
Hi,
Just a suggestion: what about making the returned array an associative
array ? Like so:array( 'quotient' => 61, 'remainder' => 1, );
This would remove the need for devs to remember the order of the return
values and would make the return value self-documenting.An associative array would combine the worst of an array (no IDE autocompletion, no strong typing, increased memory usage) with the worst of an object (no easy way to extract the values into local variables with array destructuring).
The example in the RFC doesn't show it, but the following makes the proposed API really convenient to use:
$slicesOfPizza = new BcMath\Number(8);
$mouthsToFeed = new BcMath\Number(3);
[$perMouth, $slicesLeft] = $slicesOfPizza->divmod($mouthsToFeed);Note how the order of values matches the words in the method name. First the result of 'div', then the result of 'mod’.
Thanks, I have added this example to the RFC (Please let me know if you have any problems).
The example has:
[$perMouth, $slicesLeft] = $slicesOfPizza->divmod($mouthsToFeed);
// $perMouth->value is '2'
// $slicesLeft->value is '2'
Shouldn't that be (without the ->value) ?
[$perMouth, $slicesLeft] = $slicesOfPizza->divmod($mouthsToFeed);
// $perMouth is '2'
// $slicesLeft is '2'
cheers,
Derick
The example has:
[$perMouth, $slicesLeft] = $slicesOfPizza->divmod($mouthsToFeed);
// $perMouth->value is '2'
// $slicesLeft->value is '2'Shouldn't that be (without the ->value) ?
I can answer this myself now :-) No, it shouldn't be, as $perMouth is a
Number object.
cheers,
Derick
Hi all,
Hi internals,
I created an RFC and put it in discussion status.
https://wiki.php.net/rfc/add_bcdivmod_to_bcmathI expect return values will probably be the main topic of discussion.
Regards,
Saki
The disscussion appears to have calmed down.
I'm going to open up voting on this on Wednesday the 17th.
Regards,
Saki