Re: [RFC] Nullable Return Type Declaration

From: Date: Fri, 15 Apr 2016 00:48:06 +0000
Subject: Re: [RFC] Nullable Return Type Declaration
References: 1 2 3 4 5  Groups: php.internals 
Request: Send a blank email to internals+get-92324@lists.php.net to get a copy of this message
On 04/14/2016 07:33 PM, Tom Worster wrote:
On 4/14/16, 5:46 PM, "Levi Morrison" <morrison.levi@gmail.com on behalf of levim@php.net> wrote:
Having a separate method instead of foo(null, "value") makes it difficult to use for the result of a function.
I suspect that might be a good thing:) I don't know for sure but the possibility exists.
Assume bar() returns Bar | Null; this would no longer work if they were separated:
    foo(bar(), "value")
Functions are often composed so if something is the output of one function it will likely be the input to another. Thus if returning optionally null values is important to you so should optionally null parameters.
This was a chin-scratcher for me. On one hand, I see what you mean. On the other I couldn't think of an example from my experience (which I admit is very narrow -- I live a sheltered life) of such a bar() that I would feed straight foo(). The semantic convention for Something or null return, as I see it, is when bar() returns null, it is saying "I got nothing". What kind of foo() does the same thing to nothing at all as it does to a Something object? This is where I got stuck. Say I was doing the composition instead via chaining. Something::bar()->foo("value") is nonsense if bar() could return null. This suggests to me that the other composition might not be wise. *Either* bar() should not be returning Something or null (maybe it should instead return some other type that can represent all the possible returns) *or* we shouldn't try to compose like this and should test for the Somethingness of bar()'s return before apply ->foo("value") or foo(…, "value") to it. Or maybe this API needs an even more fundamental redesign. So, from my perspective, this might be an example of the limitation nudging us to think harder about the design. Tom
I have to agree with Tom. if foo(bar(), $val) could die because bar() may return NULL, that's not an indication that foo() needs to accept NULL. It's a sign that bar() should not be returning it in the first place. :-) I am highly, highly sceptical about nullable parameters or returns, and frankly would rather they were not included in the language. By nature they undermine type safety. At best, they indicate to all callers "*every* time you call this function, you MUST put is_null() around it or your program may fail randomly." While that's better to know explicitly than not (which is the case for any untyped return, aka any PHP code pre-7.0), it would be better still to, well, not have to worry about that billion dollar mistake[1] cropping up in my code. In a sense, if we really must allow for value-or-null (which I consider a code smell in the 98% case) I'd prefer if it was ONLY available via union types: That is, Something|null. That's longer and clumsier to type, and harder to read. Which it should be. (Static casts in C++ have a fugly syntax, which has been defended by the language designers on the grounds that static casts are fugly, so the syntax for them should be as well to remind you to stop doing it. There is a fair amount of validity to that argument on affordance grounds, at least within C++.) Using an easy short hand notation for something that is inherently a code smell when you're already typing your code only serves to encourage something we should be training people out of in the first place. Unless you like having is_null() scattered around your code in a hundred places... I don't. :-) [1] https://en.wikipedia.org/wiki/Tony_Hoare#Apologies_and_retractions --Larry Garfield

« previous php.internals (#92324) next »