Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:108067 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 88904 invoked from network); 9 Jan 2020 17:25:10 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 9 Jan 2020 17:25:10 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id BB18C180504 for ; Thu, 9 Jan 2020 07:30:50 -0800 (PST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,HTML_MESSAGE, RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_PASS autolearn=no autolearn_force=no version=3.4.2 X-Spam-ASN: AS15169 209.85.128.0/17 X-Spam-Virus: No X-Envelope-From: Received: from mail-lf1-f44.google.com (mail-lf1-f44.google.com [209.85.167.44]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Thu, 9 Jan 2020 07:30:50 -0800 (PST) Received: by mail-lf1-f44.google.com with SMTP id 9so5485936lfq.10 for ; Thu, 09 Jan 2020 07:30:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=bMZBljtavE8UjekDf/SPUSuDIO+7bnJF3fw8JCEEyeo=; b=vMPAJmQaJ4vBYXpR0QyUV12pkuW0gQp5srpU8ibcE1lKfKR4HNM0etCDX5jSDj4jEJ 3l/n34YDwB5W6jiYYblxYAPrh3aWLtS4sqRaW2hDvmxLuodkaEDQPc3AJMXl41qYYSzf LOT1dISen9cCxL/oATybXLVLtqEL6QI/2q1vgp+wXIqd190oIP8qCo4z3HCD33vu9aYQ pCkto+qlIlEKI3SdczkGNwNwviLy/NYqdXdBlvRloNoF7/2BEkydTe20MWciny7NUyar ADpha6HF7pl+xJQxK1pQSn9WGGkpFX3b/FWCgfgt4T49hBGhqA+tw5EN4WjRx4Qv0huB AWjg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=bMZBljtavE8UjekDf/SPUSuDIO+7bnJF3fw8JCEEyeo=; b=fqXu3wkgw9idztPLmmUnSIsxZmclrmXb1oy4gVATlmhoLYrV1orbsu8OuMIl49IiCL AGyOJ69Nztpuc9APZkp1rp8YnRRcaIOZqy2GlMbg0j9Q+UtZZI16luqVpMh9TKYfToh9 KlRVDhnWogcc3VYnzZ9ca4ch7BkAyQweQgJCNRmjkFTFv20laoToBX5FqPhJ1G/1E3TO ldGp3rDCSXnH5wyqzHCyGRtBINQt/ghITT+NVjPnTA0KGZBPRAOEwEZJs6ZWxovFG+I5 eT6gLSsOE0+CsWyzdU6EbEfUfn86GzSRutz4vU8wXZ8/oQIxDEXKd1XNTRwoOSSV00VA zIaQ== X-Gm-Message-State: APjAAAUsUCksoMspUzEyUPM6oSf8xXwLEo1vBhwQVNathF4mSC/TqYI5 rNpf4X3PSxvtJjLtkKyIIoy0VoML5sN0z9S+euOusBn3 X-Google-Smtp-Source: APXvYqzKDR4+4R0Qa5mwO7XJNOI47bHGR2JUGIsV+T6U3hVZH0V2DV5no96qSCV8oXgotEN+KL+Qc/rRxR11lFN2vP8= X-Received: by 2002:ac2:430d:: with SMTP id l13mr7026956lfh.112.1578583846638; Thu, 09 Jan 2020 07:30:46 -0800 (PST) MIME-Version: 1.0 References: In-Reply-To: Date: Thu, 9 Jan 2020 16:30:30 +0100 Message-ID: To: Rowan Tommins Cc: php internals Content-Type: multipart/alternative; boundary="0000000000006d5ab1059bb6b18a" Subject: Re: [PHP-DEV] [RFC] Static return type From: nikita.ppv@gmail.com (Nikita Popov) --0000000000006d5ab1059bb6b18a Content-Type: text/plain; charset="UTF-8" On Thu, Jan 9, 2020 at 4:06 PM Rowan Tommins wrote: > On Thu, 9 Jan 2020 at 14:23, Andreas Hennings wrote: > > > > However, $this is not a real type, and it is unclear what the advantage > > of specifying $this rather than static would be from a type system level > > perspective. > > > > Perhaps not from a "type system level", but from a more broad "enforced > > contract" level. > > E.g. IDEs or code inspection tools can warn if a method will not return > > $this. > > This also means recursive calls also need to return $this instead of > > static. > > > > class C { > > function foo(): static { > > return clone $this; > > } > > function bar(): $this { > > return $this->foo(); // IDE can complain. > > } > > } > > > > > I think there are two different purposes for annotating return types: > > 1) Contracts that tell the caller what values they should expect when > calling the function. > 2) Constraints on the implementation which don't affect the caller, but > allow the author to catch certain bugs. > > The primary purpose, in my mind, is (1), with (2) generally coming as a > side-effect: if your contract is to return an int, then tools can warn you > when you don't. > > All concrete types can be seen this way: scalars, classes, and pseudo-types > like "iterable" are all contracts that calling code can rely on. "self", > "parent", and "static" fit into that list fine, because they're ultimately > specifying a class name. > > The special "void" keyword doesn't actually make sense as a contract given > PHP's calling convention - as far as the calling code's concerned, it's > equivalent to "null". So it exists only for purpose (2), constraining the > implementation for the benefit of the function's author. > > $this would fit into the same category - as far as calling code is > concerned it is equivalent to "static", unless they're doing something very > specific with object identity. This makes it an odd constraint on > interfaces, for example - DateTimeInterface exists specifically to have > mutable and immutable implementations, and a return type of $this would > explicitly prevent that. > > If we add ": $this" alongside ": void", I wonder where that takes us next - > what other constraints on a function can be expressed using that notation > which aren't contracts on the value seen by the caller? If we don't want to > explore that question, should we avoid adding ": $this"? > An argument could be made that $this does also specify a certain contract to the caller: That the API may be used fluently or not without change in functionality. That is $foo->setBar(); $foo->setBaz(); must be strictly equivalent to $foo ->setBar() ->setBaz() ; The same is not the case for a plain "static" type. In fact, I think that for all other uses of "static" outside of fluent interfaces, not using the return value would be a programming error. But still, this kind of contract is not a type-system contract, and I'm not sure it's a good idea to mix other types of API contracts into the type system in this fashion. Regards, Nikita --0000000000006d5ab1059bb6b18a--