Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:115735 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 67964 invoked from network); 15 Aug 2021 09:50:34 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 15 Aug 2021 09:50:34 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 4998D1804B3 for ; Sun, 15 Aug 2021 03:22:15 -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=-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-f51.google.com (mail-lf1-f51.google.com [209.85.167.51]) (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 ; Sun, 15 Aug 2021 03:22:14 -0700 (PDT) Received: by mail-lf1-f51.google.com with SMTP id i9so7847635lfg.10 for ; Sun, 15 Aug 2021 03:22:14 -0700 (PDT) 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=zEffnJXf9HUy16AQRtQrdBY2mKeF34I0yVGvw/yzu6A=; b=FATVhmon7rbTtXDP/WUPfufyJ2Y0b6SOPIvl6byxcrOg8io3hBeiohg0HjZBWbakRm +fvehrKaDz/w0bsi/F3zMsN1KlvV6hyHSm8CZuI/cu/hJd8LFAr8RAbwHIRD7PRn7I37 X/s2WXCOzQVhRccSVC7+8WRA+8JPdWNZakxISnv/Uob0/DqLYmcPaAYhp5mhQ7pnr2dk eTzV58vz58BNQpKuec8l8q8XcZ4qsmualot2dDSBnzm+u4qNUGBiKGna0sxYlEVtPOfO VHagNSFpIt/LlFMtARvD8TczYKwgyj4YqUx9LkzSFoEHtkJqJrgqnV/zxmPB6ZBYY/rB VBtQ== 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=zEffnJXf9HUy16AQRtQrdBY2mKeF34I0yVGvw/yzu6A=; b=uhsjYyZPWKX3lz6rlXpX6yHpgG6SEcBfEu9Vudr24LSyozY78OiwOC3eOskLrsHtc2 61xLVb68nEmiitQWaQNXGOJx05eZhgh8C4iHdipPMZ9YDM4TQmcuSAxc38q1btyHS6So gUePfiXUeXAYjWaCrpXCn/hwquXDCHN+ChColCBGPEl/SnBnyMVUU4j2mm+JiLr4F0j4 oJ5Wse22WuhpONOV4qbHfn/Q1BlrwkmvUD/BE12macSRPMa52qH2z6vlC4hax6lfW3ay VHfYER7ELqeiMznOTCXVJQc/G9h8qmLd4OuAI4crznMabITPvfbfRe/15cqi/aJywcbL 6I6Q== X-Gm-Message-State: AOAM533pzDO2hgk1lC+sDKkbTedfQ0TAi6bjtMdpUzeH+lFgtboDiSl1 q99z+/ElUGupP/3q8x8Fu64tNLcZ1psf1W4yGEg= X-Google-Smtp-Source: ABdhPJwX5sM7gc9nGrWDX/cbzEDD07uA8U3JyOse472G/T3lbA2+W3WdNzIsQoqJHGqfcK7pRZpvIVBTxWGzONs9NPI= X-Received: by 2002:a19:7619:: with SMTP id c25mr61500lff.564.1629022932454; Sun, 15 Aug 2021 03:22:12 -0700 (PDT) MIME-Version: 1.0 References: <64b3800a-c54e-c1cc-8bab-bc503a969c37@allenjb.me.uk> <954A89A5-97D4-491E-ABFC-CC2BE4FF87BA@newclarity.net> In-Reply-To: Date: Sun, 15 Aug 2021 03:22:07 -0700 Message-ID: To: =?UTF-8?Q?Ond=C5=99ej_Mirtes?= Cc: PHP internals Content-Type: multipart/alternative; boundary="0000000000003850ad05c996755d" Subject: Re: [PHP-DEV] [RFC] Never For Argument Types From: jordan.ledoux@gmail.com (Jordan LeDoux) --0000000000003850ad05c996755d Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Sun, Aug 15, 2021 at 1:25 AM Ond=C5=99ej Mirtes wrote= : > It=E2=80=99s true that having =E2=80=9Cnever=E2=80=9D in a parameter type= (please use =E2=80=9Cparameter=E2=80=9D > name for the method declaration, =E2=80=9Cargument=E2=80=9D is what you p= ass to a parameter > when you call the method) would allow to use any type in an overriding > method from contravariance/LSP point of view. But at the same time the > interface with the =E2=80=9Cnever=E2=80=9D parameter type isn=E2=80=99t u= seful at all, because > =E2=80=9Cnever=E2=80=9D cannot accept any type. > I fixed the parameter/argument discrepancy in the wiki version of the RFC and the pull request already. :) > > Same as =E2=80=9Cnever=E2=80=9D in a return type means =E2=80=9Cthis func= tion never returns=E2=80=9D, > =E2=80=9Cnever=E2=80=9D in a parameter type means =E2=80=9Cyou can never = call this=E2=80=9D. > > That=E2=80=99s because if you have interface =E2=80=9CFoo" with method "d= oFoo(never $a): > void=E2=80=9D, you might be able to override it with =E2=80=9Cclass Bar i= mplements Foo=E2=80=9D and > method =E2=80=9CdoFoo(A $a)=E2=80=9D, but at the same time it only allows= you to call > =E2=80=9CBar::doFoo(new A())=E2=80=9D, it doesn=E2=80=99t allow you to ca= ll =E2=80=9CFoo::doFoo(new A())=E2=80=9D. > Which is probably not what people expect from a polymorphic method. So > having the method on the interface =E2=80=9CFoo=E2=80=9D is completely us= eless. > > Ond=C5=99ej Mirtes > I understand the point you are making, but my answer would be two simple points: 1. Mixed is equally useless (in a different way). It's so much so, that it's literally the same as not providing a type at all. Omitting types is assumed to be mixed. While never is unhelpful in terms of static analysis, mixed is unhelpful in terms of semantic correctness of the code itself. I would argue that the issues around mixed are worse, because they create problems in actual programs... never only creates problems for IDEs and static analysis tools. And that's not me arguing that mixed should be removed (not that it could be). My point is that the top type and the bottom type in any type system are always going to have some inherent limitations in one direction, while being inherently limitless in the other direction... that's what makes them the top type or bottom type. 2. Interfaces have more purposes than just standing in for classes in a type hint. Interfaces also guarantee an implementation. The ArrayAccess interface is really the shining example of this RFC. It's parameters are all typed as mixed, which prohibits any implementing class from typing at all. This is strictly incorrect. The key cannot be, for instance, null or a resource. Well... okay, I can think of some really terrifying ways you *could* do that, but I think my point stands. The types for all the parameters in the ArrayAccess interface should be never, because it is the bottom type. What the ArrayAccess interface indicates is that the engine can treat the object like an array for the purposes of the `[]` operators, but lots of code which implements the interface has to do all kinds of type checks that should be unnecessary due to the requirement of typing the parameter as mixed. So I guess what I'm saying is that all the limitations and drawbacks of using this type that you mentioned are 100% true. But I don't think that's a good reason to reject the feature personally. It would not be correct for every interface to type all parameters as never if this were passed, the same way that it wouldn't be correct for all interfaces to type all parameters int. The never type does not fit all use cases, but for the use cases it does fit, it helps avoid a lot of unnecessary code, it helps make code more correct and safe, and it improves run time consistency. This RFC is not about formalizing the never type. I think that's a good follow up to this one, personally. That would involve formalizing the set theory of never as the bottom type (which would involve some changes to unions and intersections, as well as probably some other changes). For instance, T|never should reduce to T if never is the bottom type, while T&never should reduce to never. Similarly, T|mixed should reduce to mixed (which it does), and T&mixed should reduce to T. I suppose, I just don't really understand this argument. It's not the right choice for every interface, but I didn't think it would be, and I hope I didn't give the impression that I thought it would be. But that doesn't, to me, affect the utility that the type *does* serve. Jordan --0000000000003850ad05c996755d--