Bringing this thread to the main one
On Sun, 24 Apr 2016 06:27:39 +0300, Mathieu Rochette <math...@rochette.cc>
wrote:
I've seen someone mentioning variadics so I made a few small tests, I
think those two should work (they currently don't):
https://3v4l.org/eZgR9/rfc#rfc-callable_typehint
https://3v4l.org/N7i0u/rfc#rfc-callable_typehint
and this one should not:
https://3v4l.org/fcRlT/rfc#rfc-callable_typehint
Hey,
You're right, this code should be valid
function foo(callable() $a) { $a(); }
foo(function (...$args) {});
But it gets into the same problems like optional params when it is typed
function foo(callable() $a) { $a(123); }
foo(function (A ...$args) {});
Now to the question why would `foo()` call `$a` with additional arguments
even though it assumes `$a` is of type `callable()`? Well at first
because it can - this is enough for it to be not type safe :P
Long answer is: in the real life there will definitely be cases where
this would allow users to shoot their feet, take this example:
function map(/* array | Traversable */ $collection, callable($value,
$index) $mapper) {
$out = [];
foreach ($collection as $index => $value) {
$out[] = $mapper($value, $index);
}
return $out;
}
...
function renderPost(Post $p, bool $asAdmin = false) {
return render("post_template", ["post" => $p, "asAdmin" =>
$asAdmin]);
}
...
$renderedPosts = map($posts, "renderPost");
// here developer would get fatal at the line `$out[] =
$mapper($value, $index);`
// if optional parameters were supported
// Without them though, he gets TypeError when he passes "renderPost"
to map()
// And it says nicely what exactly he has done wrong
Even now though, he could get into this situation if `$asAdmin`
parameter was not properly typed, but that would be on him as
he'd need to voluntarily drop those types for which I don't see
a reason to do so.
Now talking about an immediate solution to hypothetical problem we are
facing
there is an easy solution - if you have a functional library, you'll
probably
have there `partial_any` function of some kind (ex. [0]),
so what you could instead do is:
$renderedPosts = map($posts, f\partial_any("renderPost",
f\placeholder(), true));
This would always pass `true` to a second parameter, but leave the first
one.
[0]
https://github.com/lstrojny/functional-php/blob/master/docs/02-partial-application.md#partial_any
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php