Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:92324 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 5354 invoked from network); 15 Apr 2016 00:48:10 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 15 Apr 2016 00:48:10 -0000 Authentication-Results: pb1.pair.com header.from=larry@garfieldtech.com; sender-id=unknown Authentication-Results: pb1.pair.com smtp.mail=larry@garfieldtech.com; spf=permerror; sender-id=unknown Received-SPF: error (pb1.pair.com: domain garfieldtech.com from 66.111.4.26 cause and error) X-PHP-List-Original-Sender: larry@garfieldtech.com X-Host-Fingerprint: 66.111.4.26 out2-smtp.messagingengine.com Received: from [66.111.4.26] ([66.111.4.26:44290] helo=out2-smtp.messagingengine.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id D8/E6-64966-94A30175 for ; Thu, 14 Apr 2016 20:48:10 -0400 Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.nyi.internal (Postfix) with ESMTP id 1A0E92097B for ; Thu, 14 Apr 2016 20:48:07 -0400 (EDT) Received: from frontend2 ([10.202.2.161]) by compute4.internal (MEProxy); Thu, 14 Apr 2016 20:48:07 -0400 DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d= messagingengine.com; h=content-transfer-encoding:content-type :date:from:in-reply-to:message-id:mime-version:references :subject:to:x-sasl-enc:x-sasl-enc; s=smtpout; bh=/ESeL4MHat8Sg7D RXg7ZeVqQ4Mc=; b=iRXYzgLD2Kfhlk7F+ywGfrDz0JBxWPnnuJyO0S59kcYc0Pz C5qtqFJRe3lIf33essALUJu7MiodIqcVVojF0rh0d4h57wjppfvjb36cpJF5FDoi 7/4L309hT6fCvge57vYXhaYZ8lzYDk5wi+T/Awv5PgDS+oP+MY9ZO4gs1ZZ4= X-Sasl-enc: y+0QQJaLcUzLjWKbmsHYLTPuu7w6OViYMuDs847c/neI 1460681286 Received: from [192.168.42.5] (c-50-178-40-84.hsd1.il.comcast.net [50.178.40.84]) by mail.messagingengine.com (Postfix) with ESMTPA id C220B68016F for ; Thu, 14 Apr 2016 20:48:06 -0400 (EDT) To: internals@lists.php.net References: Message-ID: <57103A46.6040803@garfieldtech.com> Date: Thu, 14 Apr 2016 19:48:06 -0500 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.6.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Subject: Re: [PHP-DEV] [RFC] Nullable Return Type Declaration From: larry@garfieldtech.com (Larry Garfield) On 04/14/2016 07:33 PM, Tom Worster wrote: > On 4/14/16, 5:46 PM, "Levi Morrison" 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