On 10/16/2015 11:56 AM, Robert Stoll wrote:
You write in your RFC "others do allow void functions in expressions,
just as PHP does, by making them implicitly return some unit type."
You mentioned TypeScript -- unit type = null -- ActionScript -- unit

To conclude, personally I want that the following are all equivalent:
function foo() : void {}
function foo() : void { return; }
function foo() : void { return null; }

To go a step further, I kind of like the idea that using the return
value of a void function results (at least) in an E_NOTICE. But maybe that is 
something for PHP 8.
I dislike this, because it punishes dynamic code (function composition).

For example:

$logUtility = partialLeft(function(string $a, string $b): void {
     syslog(LOG_INFO, $a . ": " . $b);
});

$log = $log("Prefix");
$log("blah"); // writes "Prefix: blah" to the log

function partialLeft(callable $cb) {
     return function($left) use ($cb) {
         return function($right) use ($cb, $left) {
             return $cb($left, $right);
         };
     };
}

Boom, notice.

Now, we could say that "that's the problem of the caller of partialLeft", but 
the notice is raised inside of the closure inside
of partialLeft. Which would imply that it did something wrong. Something that 
it couldn't possibly know about without
booting a reflectionfunction for it.

This would mean that generic higher order functions would need to be 
duplicated, one for void functions and one for non-
void functions. A bit overkill...

That's just my $0.02

Anthony
I agree only to a certain degree. If you had not used the type hint callable, 
then I could argue that the same applies for passing null to partialLeft.
Hence, the problem is rather that PHP does not yet support callable type hints 
with return type, something like callable:int, in which case it would be clear 
that the error was done by the caller.

That wouldn't help either, I think. Then you'd need a separate partialLeft(callable:int $cb), partialLeft(callable:string $cb), partialLeft(callable:float $cb), and partialLeft(callable:void $db). And likely others. That seems exactly like what Anthony wants to avoid (rightly).

Indirect calls to arbitrary functions does mean that they need to be able to behave consistently when referred to abstractly. Vis, any approach that involves:

function foo() : void {}
$a = foo();

triggering an error condition would make life drastically more difficult for higher order function operations like partials or memoization. That seems doubleplusungood.

One way around that would be to only trigger that behavior on a static call, not a call to a variable function, but I have no idea if that's at all feasible in the engine. I suspect it's more feasible than detecting the function wrapping and only erroring at the top level caller, but now I'm just talking out of my butt. :-)

That leaves "documentation of intent for the developer" (which is a valid argument) and "slap someone's hand for returning non-null inside the function itself" (which is valid, but leaves the question of whether return null should error).

--Larry Garfield

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

Reply via email to