Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:92325 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 16415 invoked from network); 15 Apr 2016 04:22:42 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 15 Apr 2016 04:22:42 -0000 Authentication-Results: pb1.pair.com header.from=morrison.levi@gmail.com; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=morrison.levi@gmail.com; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.220.65 as permitted sender) X-PHP-List-Original-Sender: morrison.levi@gmail.com X-Host-Fingerprint: 209.85.220.65 mail-pa0-f65.google.com Received: from [209.85.220.65] ([209.85.220.65:33457] helo=mail-pa0-f65.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 38/B7-64966-09C60175 for ; Fri, 15 Apr 2016 00:22:40 -0400 Received: by mail-pa0-f65.google.com with SMTP id vv3so8351176pab.0 for ; Thu, 14 Apr 2016 21:22:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:in-reply-to:references:date:message-id:subject :from:to:cc:content-transfer-encoding; bh=2b+aWeZuSp8VEkXby78pVo+bZVVGUxL6XIsrPGKX6o4=; b=y2tEt+uC9BhAOwQ4Ghx+ZBFpc5xGzQwkSdIp9aN3Nddo7x90xp0DTOyQqQR8ghdRP3 9CbsWY1l4yirySiSa01GGj59/Zo99G1auqSRQOO7SUZ3MTJXYFraLw9HKpqInQ71WEFE aWPSApiMyXUFQVJOslaZn87HKClDkyoI31Hi9J/jO/xHRLJ+ooyJSJfdcghZaGkuwKWs 5e6nR3m3HsK90OWZMSe30G85LhLkeoMPCVt4nGXee8shG0biG3ZDu9h5+vKAE2qXqWpY BxDUO29hXgLADNGw0hKPsJeCp8Q6en1M3Evu5cfkOEm0Acg4LmsWYXCerAujS2LBYZHu rP+Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:sender:in-reply-to:references:date :message-id:subject:from:to:cc:content-transfer-encoding; bh=2b+aWeZuSp8VEkXby78pVo+bZVVGUxL6XIsrPGKX6o4=; b=gO84ZxVgPJ+XO7PsXv3mdLdgMIXkbrXc3REpcIeW2zg019aGx6t2ImQd+SceJB9Chw NaoLtAgT+4HQL0rdDXJnGRHsh5jDH1ynN66fGEZnYZjnJLGO1j1d2vuTFuOBGmHTXt9S gnJIjI1uCdFxewFSXRSzhhmJzEqobG+eBJqkeaP6WlsQVaj7pzZWgsrDRxH/ye5LC9E/ 4PV6hqjRhDYwD8jUKNrMrloEt6zlBl+RL7NyUWzHZohUcBL3bQYhQWduJawlO+y8k4Z8 EySkcn2dBKQf8Cdl6K7G8fmlqM8B5xWK5WecPYKgiD8hTe1c6uA1RZWXBP3vF4jJoryT 0yJg== X-Gm-Message-State: AOPr4FUGXAKWEylGoxdbhtbYXoSbLwN6KfVYYKGrzwfeGNofUMO9tA91gaTioA5GFZOq+M0FG2QXkCqv4ggfNg== MIME-Version: 1.0 X-Received: by 10.66.66.42 with SMTP id c10mr26290144pat.119.1460694157496; Thu, 14 Apr 2016 21:22:37 -0700 (PDT) Sender: morrison.levi@gmail.com Received: by 10.66.163.232 with HTTP; Thu, 14 Apr 2016 21:22:37 -0700 (PDT) In-Reply-To: <57103A46.6040803@garfieldtech.com> References: <57103A46.6040803@garfieldtech.com> Date: Thu, 14 Apr 2016 22:22:37 -0600 X-Google-Sender-Auth: 9GhmtdywegHSvkFr4enybJtWnOc Message-ID: To: Larry Garfield Cc: internals Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Subject: Re: [PHP-DEV] [RFC] Nullable Return Type Declaration From: levim@php.net (Levi Morrison) On Thu, Apr 14, 2016 at 6:48 PM, Larry Garfield wr= ote: > 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 t= he >> other I couldn't think of an example from my experience (which I admit i= s >> very narrow -- I live a sheltered life) of such a bar() that I would fee= d >> straight foo(). >> >> The semantic convention for Something or null return, as I see it, is wh= en >> bar() returns null, it is saying "I got nothing". What kind of foo() doe= s >> 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 shoul= d >> 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(= =E2=80=A6, >> "value") to it. Or maybe this API needs an even more fundamental redesig= n. >> >> 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() ma= y > return NULL, that's not an indication that foo() needs to accept NULL. I= t'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 t= hey > undermine type safety. At best, they indicate to all callers "*every* ti= me > 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 i= s > 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 shor= t > 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 My point is that `foo(bar(), $val)` won't die because bar may return null. Bar is expected to return null sometimes. For example, let's consider an administrator page where they look up user information based on an identifier. The routine we'll use will have this signature: function get_user(string $id): User | Null; It is possible for an identifier to not exist and this is not an error (database successfully returned no results). If there is no User data to display then it makes sense for the UI to present that differently. Thus it makes sense to pass that User | Null onto the code that will present it: $user_data =3D get_user($id); // ... $user_html =3D render_user_data($user_data); In fact this is a common operation that is encountered in many code bases (I think every single one I've ever looked at).