AW: AW: [PHP-DEV] Re: [RFC] Void Return Type (v0.2, reöpening)
| From: | Robert Stoll | Date: | Mon, 26 Oct 2015 10:10:47 +0000 |
| Subject: | AW: AW: [PHP-DEV] Re: [RFC] Void Return Type (v0.2, reöpening) | ||
| References: | 1 2 3 4 5 6 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-88938@lists.php.net to get a copy of this message | ||
Hi Larry,
> -----Ursprüngliche Nachricht-----
> Von: Larry Garfield [mailto:larry@garfieldtech.com]
> Gesendet: Samstag, 24. Oktober 2015 00:36
> An: internals@lists.php.net
> Betreff: Re: AW: [PHP-DEV] Re: [RFC] Void Return Type (v0.2, reöpening)
>
> 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
>
> --
Well, it really depends on the use case. I would probably not write such a generic partial function,
especially not allowing functions which return a value and others which don't. I could imagine
to use callable:mixed to allow values of arbitrary types to be returned. Yet, that would still not
include a function which does not return a value. IMO we do not really proceed further with this RFC
when discussing this special case - callable:int, callable:mixed etc is not supported by PHP now, so
we should focus on the essential now.
IMO we should get an agreement what void means in PHP, I see the following options:
1 void is a type with a value set containing null (ergo corresponds to the set { null }) and hence
it is perfectly fine to return null from a function with return type void (naming it void is
controversial among the list -- others prefer null -- but that can be discussed further afterwards)
2 void is a type with an empty value set (a special value respectively) and hence one cannot return
null from a function with return type void and
a) such a function returns null implicitly nonetheless
b) such a function returns a special value which triggers a fatal error when it is accessed
IMO 2a is inconsistent and I would only consider 1 or 2b