Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:115731 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 38462 invoked from network); 15 Aug 2021 01:26:56 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 15 Aug 2021 01:26:56 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 95F4D1804B3 for ; Sat, 14 Aug 2021 18:58:28 -0700 (PDT) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_NONE 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-qv1-f53.google.com (mail-qv1-f53.google.com [209.85.219.53]) (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 ; Sat, 14 Aug 2021 18:58:28 -0700 (PDT) Received: by mail-qv1-f53.google.com with SMTP id c14so3527977qvs.9 for ; Sat, 14 Aug 2021 18:58:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=newclarity-net.20150623.gappssmtp.com; s=20150623; h=mime-version:subject:from:in-reply-to:date:cc :content-transfer-encoding:message-id:references:to; bh=yMQeCZWDL8ZfNwUrNoQ1vcdCpPucbMgSEfear3MlJ9Y=; b=s+fmn10h8mQ0XRe9yqfTzeIRdFeinykGeRcQ4l6rMN/avSpobx/m/7M+Vlm9h0JEsZ DlVQTi9aSc8XqH1FrdWLogEGzxI0cBsPcMpObDVxq2syxTcqwfBSdlTmOxDusFs/AMwo byuqlIMnWJiN7mjn+M8YDp/8O6Lc3zB8gD7mPOjny+DJjX1GxYZK5KZpFBBHQQ05oNlk SVsNzNgVay7/bM1lQ0QgN+v9sHo3u7As0u7mKOk/D7rvDqQ3lUjlC/EFCaJTBeZaCpZf MDuU3S6Nj6SzsPgG7mGuaCRcJ7StGD4Rbjchfez+mvMuv7QBpHAFSlt0l69Zvyy31lZV uZUQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:subject:from:in-reply-to:date:cc :content-transfer-encoding:message-id:references:to; bh=yMQeCZWDL8ZfNwUrNoQ1vcdCpPucbMgSEfear3MlJ9Y=; b=WrnMOaxeHf1eV2Z6WmixQNHEzG/8/d4BzhdM1k6ZdOXzsxtrL9MKBpiBTC+GgtvjPh PlCysMFhEAeTX+P0yoJ3CCVU9l9KilT9+39M9uQbgbWG/eZMA9d/RtLDWYb+MffMNrSM MI1JEdWZkypDdTDqOBIjWVmhG9K02R2nMlDfXCOYjo879ryh0rYDy8Yqlq84HKLsva/J 0rg4DwjVBA1tmhYIjRAqX3DbdTMSPtvZAECrBQ2ioZ2TQmgetKbH1NwqgjP3ixby+0DJ MDbhXVKgl9zzYMJSu6BSjQrzsHRtiMhXwggzpf88Xnlo7FFjK/UFvzhPYHBJJ9Vdchyy PZHA== X-Gm-Message-State: AOAM533OFkuyWdS73oQ/yOM2wmSR20+qBG2y9eowEk4jBcUSeMGdatoa U1xCKGevS0fdBGVMAhEbNWFlfA== X-Google-Smtp-Source: ABdhPJzvV69YqXYegphWShFgCq6g1ioKweJryhdmdkLaPXVfuugcVa9pXZ4WYRaB7fbPqDuqNROpRw== X-Received: by 2002:a05:6214:e62:: with SMTP id jz2mr9778738qvb.21.1628992706690; Sat, 14 Aug 2021 18:58:26 -0700 (PDT) Received: from [192.168.1.10] (c-24-98-254-8.hsd1.ga.comcast.net. [24.98.254.8]) by smtp.gmail.com with ESMTPSA id y124sm3838058qke.70.2021.08.14.18.58.25 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sat, 14 Aug 2021 18:58:25 -0700 (PDT) Content-Type: text/plain; charset=us-ascii Mime-Version: 1.0 (Mac OS X Mail 13.4 \(3608.120.23.2.7\)) In-Reply-To: Date: Sat, 14 Aug 2021 21:58:24 -0400 Cc: PHP internals Content-Transfer-Encoding: quoted-printable Message-ID: <954A89A5-97D4-491E-ABFC-CC2BE4FF87BA@newclarity.net> References: <64b3800a-c54e-c1cc-8bab-bc503a969c37@allenjb.me.uk> To: Jordan LeDoux X-Mailer: Apple Mail (2.3608.120.23.2.7) Subject: Re: [PHP-DEV] [RFC] Never For Argument Types From: mike@newclarity.net (Mike Schinkel) > On Aug 14, 2021, at 10:40 AM, Jordan LeDoux = wrote: >=20 > Never is treated as the bottom type for the purpose of Liskov = substitution > already with its use as a return type. The exception to this in its = use as > a return type is that it isn't treated as the union identity in the = return > type. However, for LSP never is the bottom type when it comes to = return > values. It would, in my mind, be highly inconsistent to have a = different > bottom type for return values than for arguments, so personally I am = very > against using a term other than never. As mentioned in the doc, I = wasn't > able to find a single existing language that has multiple bottom = types. If > anyone is able to provide an example of this, I would appreciate it. Reading through all the replies on this topic it seems that the = functionality for the proposal is less controversial than the keyword = chosen to identify it. =20 It occurs to me that while `never` is the correct keyword for the bottom = type given past decisions, maybe choosing to use a bottom type to = provide this functionality is not an idea choice? If we approach this use-case requirements from a perspective of "this = keyword indicates that you must implement in a child" then I think we = already have a keyword that has appropriate semantics compared with the = confusing semantics of `never` used for a parameter: `abstract`. So then instead of `never` we could choose the following: interface CollectionInterface { public function add(abstract $input): self; } `abstract` could also work for return types and property types: interface Foo { public abstract $bar; public function baz(): abstract {} } Or am I missing something? Is there a reason `abstract` would not be a = better choice than `never`? =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D That said, I do have a rhetorical question to ask, to be pondered by = those who are better attuned to the ramifications of allowing interfaces = to become less strict than they already are. =46rom my career-long understanding of declared interfaces the primary = (only?) reason to use them is to signal and enforce a guarantee that a = specific set of signatures are available in an instance of a class that = implements the interface. But if an interface can be defined as = something that can can easily change based on the implementor, the = guarantee that we could previously depend on its signatures will no = longer be, well, guaranteed. My gut feeling tells me that will be a bad direction for us to take with = PHP. What do other's think? =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D After writing the above it occurred to me the solution to the above = problem already conceptually exists, too, classes get to use the = `abstract` keyword when their children need to be required to implement = something. If PHP requires interfaces with parameters defined as type `abstract` = (or `never` if we must) then those interfaces should also be required = to be declared `abstract`: abstract interface CollectionInterface { public function add(abstract $input): self; } Class IntCollection implements CollectionInterface=20 { public function add(int $input): self; } The primary tangible difference between abstract and concrete interfaces = would be in documentation, reflection, and possible an is_abstract() = function so that code that needs to ensure an exact specific interface = could do so. The benefit of this approach as it appears to me is that (concrete) = interfaces can retain their same level of guarantee where abstract = interfaces would not be required to maintain such a guarantee. #jmtcw Thoughts? -Mike