Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:115539 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 92359 invoked from network); 21 Jul 2021 06:39:59 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 21 Jul 2021 06:39:59 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id BC4C71804C8 for ; Wed, 21 Jul 2021 00:05:22 -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_H3,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE, SPF_PASS autolearn=no autolearn_force=no version=3.4.2 X-Spam-Virus: No X-Envelope-From: Received: from mail-ej1-f49.google.com (mail-ej1-f49.google.com [209.85.218.49]) (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 ; Wed, 21 Jul 2021 00:05:22 -0700 (PDT) Received: by mail-ej1-f49.google.com with SMTP id dt7so1629653ejc.12 for ; Wed, 21 Jul 2021 00:05:22 -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=nVQkYt34MeGMdGzRSZytaFHbp/vXpLwOu3uk/6f3f1Y=; b=UqD0qUoh03oxmHY/JS/aL0kJ0gDhYcGRWiQ9npT5u4PKk8DBFAlyQYrAH6p27tNz1Q CEDoxhkdZ6uYDpZF32/kDU/qyY2XJsyrHmLypRKcXGPfX/E99sElwvqeqMUtGXBgZcFO 21Rc+wzVcN3YRmXvnpOh9QWWFuoORSbD72HzOZGv1dSaT4G5duPOWfv8y+W+cvOA24DO bpEj2OfSY65mTY762U87a076CXipO7MtsaapxCtE7GqcKFh4r+vIqrP/pCxHof3pNoA/ HqgOJ9ffS9s8mR3A3yDrAycxg/2Tljhmgogi2O+XXejw0J/c1wutCvAjKazJLmp5Iz/C z0HQ== 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=nVQkYt34MeGMdGzRSZytaFHbp/vXpLwOu3uk/6f3f1Y=; b=SAICHMo/4CvhDeFhA5tSbEcL1GwqRkyfGCJrUSk3XnJcfpiTckKEFjApNCV3RTaedU gJTogOgcGQEDWwdMTHM2o35plJdlmvxIGkzsQBWk1IQ+e+8MoW49IsYr3Hh04Up2qf/K 33TRsdmPlKJaWp1JeywfjJF9FAjpEaTCcR5pc7PS0bUEbW03N6kK625YFA41dygqvG3L wgCX33vkYnH80nuFTDaeG4pbkU/9dGdLOd5aKtHS3lORSDI4ZRsq22PrkSaTwCT4zIE7 HYljrB+Kv7qBaJ0aUikOu9qcgB88+hBHP/FssZCHqH/lE1obUvN8ptqOSgbbg2fZ0iq3 WKzA== X-Gm-Message-State: AOAM533BGPVdIu5s0EkDAowtnlOoPNfKbQhEQN18SMLQ/4lU9EPxHek5 tp9fxLfmnP+bhRvNAHBeVCNPoWud3rsEmrGvdjg= X-Google-Smtp-Source: ABdhPJwu77YCTLS/BW+ixfjKjCzWhnOkLz/AyCjYCnJvRweVBPZtP3rbFSXdsnVb795sl84heExqPk9TDwopKUPCWrA= X-Received: by 2002:a17:906:131a:: with SMTP id w26mr37425076ejb.46.1626851120073; Wed, 21 Jul 2021 00:05:20 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: Date: Wed, 21 Jul 2021 09:05:06 +0200 Message-ID: To: Joe Watkins , Nikita Popov Cc: PHP Internals List Content-Type: multipart/alternative; boundary="0000000000001d50a805c79ccb87" Subject: Re: [PHP-DEV] intersection types and null for defaults, properties and return types From: nicolas.grekas@gmail.com (Nicolas Grekas) --0000000000001d50a805c79ccb87 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Le mar. 20 juil. 2021 =C3=A0 14:41, Joe Watkins a =C3= =A9crit : > Agree, an RFC looks like the only way. > > This is not worth delaying a release for, nor is it worth postponing the > feature freeze date. > > It seems reasonable to fix this after freeze, would prefer to reach > consensus before RC stage. > > Cheers > Joe > > On Tue, 20 Jul 2021 at 13:07, Nikita Popov wrote: > >> On Mon, Jul 19, 2021 at 8:16 PM G. P. B. >> wrote: >> >> > On Mon, 19 Jul 2021 at 18:26, Guilliam Xavier < >> guilliam.xavier@gmail.com> >> > wrote: >> > >> > > On Mon, Jul 19, 2021 at 4:26 PM Nicolas Grekas < >> nicolas.grekas@gmail.com >> > > >> > > wrote: >> > > >> > > > >> > > > https://github.com/php/php-src/pull/7259 >> > > > >> > > >> > > Great! Thanks! Interesting how it works out-of-the-box with just thi= s >> > > addition in Zend/zend_language_parser.y: >> > > >> > > ```diff >> > > type_expr: >> > > type { $$ =3D $1; } >> > > | '?' type { $$ =3D $2; $$->attr |=3D ZEND_TYPE_NULLABLE; } >> > > | union_type { $$ =3D $1; } >> > > | intersection_type { $$ =3D $1; } >> > > + | '?' intersection_type { $$ =3D $2; $$->attr |=3D ZEND_TYPE_NULLA= BLE; } >> > > ; >> > > ``` >> > > >> > > On Mon, Jul 19, 2021 at 5:09 PM Dan Ackroyd >> > > wrote: >> > > >> > > > nicolas-grekas wrote on the PR: >> > > > > ?X&Y cannot be confused with >> > > > >> > > > It confused me. A compiler might understand it, but as a human I >> have >> > > > trouble understanding it. >> > > > >> > > > Trowski wrote: >> > > > > The syntax should be either ?(X&Y) or (X&Y)|null >> > > > >> > > > Non-ambiguous syntax is much better than ambiguous syntax. >> > > > >> > > >> > > Maybe it's just a matter of habit? >> > > For instance I got used to seeing things like `!$x =3D f()` (e.g. `i= f >> (!$x >> > =3D >> > > f()) { throw /*...*/; } /* use $x */`) because some CS consider >> explicit >> > > parentheses in `!($x =3D f())` redundant (as PHP has a special case = that >> > > "overrides" the normal precedence `(!$x) =3D f()` which would be an >> error). >> > > If you first consider `X&Y` as a type "unit", then it makes sense to >> make >> > > it "nullable" by prefixing it with `?`, I think? >> > > >> > > >> > > > >> > > > But this discussion is moot for 8.1. >> > > > >> > > > This limitation might make intersection types not be considered >> usable >> > > > by some projects, but the feature freeze is today. >> > > > >> > > >> > > Which can also be reversed: "The feature freeze is today, but this >> > > limitation might make intersection types not be considered usable by >> some >> > > projects"? (playing devil's advocate, I don't master the process) >> > > >> > > Regards, >> > > >> > > -- >> > > Guilliam Xavier >> > > >> > >> > Since when is usability for a specific project a consideration an RFC >> needs >> > to have? >> > If Symfony can't use it in its current state tough luck, >> > I'm sure plenty of other projects can, especially now that using 'new >> > Class' is possible as a default object value. >> > >> > I frankly don't care about being able to have some sort of partial uni= on >> > possible with the usage of intersection types, >> > because it seems the machinery in the engine which makes null work, >> should >> > also allow any standard PHP types as those are part of a bitflag and >> > handling variance with them seems to work just fine... >> > >> > But for the love of god, this proposed syntax is horrendous, saying >> ?X&Y is >> > unambiguous is disingenuous. >> > It can either mean (?X)&Y =3D (X|null)&Y or ?(X&Y) =3D (X&Y)|null, the >> former >> > one being bogus as null&Y is an impossible type, something which shoul= d >> > error out to point out a potential bug in the same way we do for >> redundant >> > types that we know at compile time. >> > And if we allow this syntax then we really should be allowing ?A|B >> which is >> > dumb. >> > (and no ?X&Y is NOT something I consider forward compatible when it is >> just >> > going to become one more edge case we need to maintain because people >> have >> > no patience). >> > >> > If ?(X&Y) is allowed then ?(A|B) should also be allowed, and that need= s >> an >> > RFC for sure due to the controversy it had in the union type RFC. >> > >> > The only remaining sensible choice is (X&Y)|null / null|(X&Y), but as = I >> > said above if the machinery for null is there it must mean the machine= ry >> > for int/string/array/float/bool is also there, and frankly being able >> to do >> > something like (Traversable&Countable)|array is also extremely valuabl= e, >> > maybe even more than nullability, but in any case this is going to be >> > confusing for end-users why only null (or standard PHP types) can be >> > combined in a union with intersection types. >> > >> > That's one reason why it's only pure intersection types, if I had more >> time >> > (or for crying out loud somebody would have paid me) to work on this I >> > would have loved to get full composite types working. >> > >> > And I find it frankly insulting that in the four month this RFC has be= en >> > published for discussion, with multiple push backs for voting due to >> bugs >> > and me wanting that people know what implementation is - for the most >> part >> > - going to land in php-src, this specific point has not been raised. >> > It just feels like you are pissing on 6+ months of *unpaid* work I did >> > because it doesn't suit your needs, and you just realised that and so >> > decided to throw a wrench into a carefully crafted RFC to "fix" it by >> using >> > a Twitter mob to put pressure on us/me. >> > >> > Maybe this topic didn't come up because for nearly everyone else "Pure >> > Intersection Types" means what it says on the can, moreso that in the >> RFC >> > the following line: >> > > This means it would *not* be possible to mix intersection and union >> types >> > together such as A&B|C, this is left as a future scope >> > makes it clear, and most voters also understood that '?' is not a type >> > "flag" but is syntactic sugar for 'null|'. >> > >> > There are plenty of issues with the implementation, from the whack >> parser >> > hack, the non support for static/parent/self, to the complexity of the >> > variance code, but I made all of those clear because they made *me* >> > uncomfortable with the implementation. >> > So if you are going to force this crappy syntax, then I'd rather axe >> this >> > feature completely (and nobody can use/play with it) then have >> something I >> > do not accept, nor are forced to accept because of a vote, land in cor= e >> > making PHP even more of an inconsistent joke. >> > >> >> Hey George, >> >> I don't think there's been any malicious intent here -- it was obvious t= o >> you and I that not allowing unions implies not allowing nullability, but= I >> can see how people less familiar with our type system implementation wou= ld >> not make that connection. After all, we do provide the separate ?T synta= x, >> even if it is an internal alias for T|null. >> >> It's an unfortunate fact of the RFC process that concerns are sometimes >> only raised when voting starts and people start looking at the >> implementation -- or in this case, when they test the implementation aft= er >> it has landed... >> >> In any case, I think it's pretty clear by now that there are some fairly >> strong opinions both on what the syntax for this should be (between ?X&Y= , >> ?(X&Y), (X&Y)|null and X&Y|null, all of which have reasonable arguments >> for >> and against) and whether we should have this special case at all. I'm no= t >> sure we will be able to reach a sufficient consensus in this discussion. >> >> For that reason, I think this change should go through the RFC process. = We >> can grant this an exemption from the feature freeze (as a clarification = of >> an accepted proposal), but it should still go through the process. >> > Thanks Nikita, Joe and the others for opening the possibility of a late RFC. I'm going to write one down asap! Nicolas --0000000000001d50a805c79ccb87--