Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:115602 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 76553 invoked from network); 28 Jul 2021 12:11:38 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 28 Jul 2021 12:11:38 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 81D8F180212 for ; Wed, 28 Jul 2021 05:38:51 -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-vs1-f54.google.com (mail-vs1-f54.google.com [209.85.217.54]) (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, 28 Jul 2021 05:38:51 -0700 (PDT) Received: by mail-vs1-f54.google.com with SMTP id j10so1306548vsl.10 for ; Wed, 28 Jul 2021 05:38:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=basereality-com.20150623.gappssmtp.com; s=20150623; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=vD707GB85cM9dj6bfYgmg1/WpuvSxWrwn4uiU4wJ6HE=; b=J8m5gAQLHMiaJtrpfqGSetdfenRnnKQjw72WNvQ/QlWpsMjx1LZGeZgdhey2hX0uIn MYGxyluLJAyk9zLRFwEE9mZO2DyYQbuzfSC08MKHRhvV1c261kOzeuXa0DUQ2Gky57FI QGQfOxH/kRGenecvO8gBYNppyF+vxnnOzRciRLk6IMY+tVke4JDCyaYfY9AiHbWNH/p/ JdIaguRZ9TD/i5/ILq+vHLxDZHaJkz1kjqI/N6NOzCS0ceV3iC92uCDO5R86AXo864+2 j/qMcjWqVikpePx3Ej2tKe/b7uyvNxDwPDgbeFSpEiPN5bx8sLlZqOqk47cAWPPqVmEv Oi0g== 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=vD707GB85cM9dj6bfYgmg1/WpuvSxWrwn4uiU4wJ6HE=; b=MbnvkgH0K1VM0L6BhOgeyaVzK3P7IxSYfArNQ1L/c6YoPhnywNZXVO7jqMFX+fekql Vf2IjHCUOtGQWO8cp255out11PNYcg0ehC2SSeNOZhAftNlCExNXQigZdP2s10lP/DzI 2iG4qP4WcypV0NWkUoA70pMA08eFxbWfERMrRE652KGWoiQfH43vkOjX3girfuw1DQXA W0iBcZIftsD3uVTAS/wgWwJRnwZ2Yq9LEzWQdaKtYlSALA9nP4q/IE6skM9qxcQvGgMo ESMGUOP0ilgIsDyHWTvZHscvqWkn/o1xqO09eGyxQJA8COi4EFQsepuQmKyZ1SFyAW/b xHsw== X-Gm-Message-State: AOAM533DiInC7fTkPel7e15W55dNO5/RoVF7Z5hbwNiVTR+BASY5buKb OQ71MDrf5pow4I1CFqTT1sbVgP9HGAqQvISG/Gai5A== X-Google-Smtp-Source: ABdhPJx/AhT+qfDubibryKHomw4VJxQUULgxtuksHy5vH07YSTVz7EF7CUzVIA3ptiqZlDUi+Q1k97RAM5ggPr8RSxc= X-Received: by 2002:a05:6102:2450:: with SMTP id g16mr6091348vss.3.1627475928729; Wed, 28 Jul 2021 05:38:48 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: Date: Wed, 28 Jul 2021 13:38:37 +0100 Message-ID: To: Nicolas Grekas Cc: PHP Internals List Content-Type: text/plain; charset="UTF-8" Subject: Re: [PHP-DEV] Re: [RFC] Nullable intersection types From: Danack@basereality.com (Dan Ackroyd) On Wed, 28 Jul 2021 at 08:29, Nicolas Grekas wrote: > Nullability is a special beast in PHP. We have a range of operators > dedicated to it. That's also why I think it deserves special care, and why > I think it's important to have this discussion before 8.1 is out. Why does this change need to be done now, rather than wait for 8.2? I can't see a clear reason in the RFC and saying 'nullability is special' doesn't seem a clear reason either. If you think you'll only be able to use intersection types when they can be union'ed with null, then ... just wait until they are? Andreas Leathley wrote: > Having one clear RFC voting option (with no > secondary syntax voting option) also seems the most honest, as if > somebody agrees that nullability would be useful but would only accept > one syntax choice, that seems impossible to represent, necessitating a > no vote on the whole RFC. I strongly agree with this. Having a situation where people will want to change their primary vote, based on which option in a secondary vote is winning is a "not good" situation. Having syntax for a type system be chosen by a popularity contest, where many of the voters are not aware of the implications of the choices is also not good. RFC authors should be trying to pass an RFC they are sure is the right choice, not leaving important decisions up in the air. Larry Garfield wrote: > Some other mechanism such as the sometimes discussed type > aliases provides an alternate way to solve this problem. This is an important point and why trying to push changes to the type system through after feature freeze is a bad idea. The example in the RFC uses single letter class names; in my experience most classes have quite a few more letters in them than that. Trying to use intersection types with realistic class names leads to code like this, for a custom cache definition*. function foo(Get|GetOrDefault|Set|SetWithTTL|GetOrGenerate|Clear $cache) { ... } Which is pretty unreadable. I don't think I'll be using intersection types much until PHP has the capability to compose types. e.g. something similar to this: type SimpleCache = Get|GetOrDefault|Set|SetWithTTL|GetOrGenerate|Clear; function foo(SimpleCache $cache) { ... } At which point the need for being able to include nullability in the intersection type goes away. You can instead use the existing ability to indicate a type can be null: function foo(?SimpleCache $cache) { ... } So yeah....I agree that widespread adoption of intersection types might not happen in 8.1 but that's fine, and better than possibly implementing the wrong thing after feature freeze. Nicolas Grekas wrote: > polishing features that are about to be released. Changes to the type system are not polish. cheers Dan Ack * Custom cache definitions. The conversation that the PHP FIG had around caching was very contentious. Everyone involved has their own idea of what features absolutely had to be in the interface, and what stuff should be left out. Some people just needed 'get' and 'set', some people needed a moderately complex cache, and other people needed an 'enterprise' level cache system that has full thundering herd protection. Trying to come up with a single implementation that makes everyone happy was an inherently impossible task. Instead of that, defining individual interfaces for each of the methods, and then allowing people to implement/use as many as they want to, allows for interoperability without having a One True Cache to rule them all, and so avoids having a prize to be fought over. So something like: interface Get { public function get(string $key): mixed; } interface GetOrDefault { public function getOrDefault(string $key, mixed $default): mixed; } interface Set { public function set(string $key, mixed $value): void; } interface SetWithTTL { public function set(string $key, mixed $value): void; } interface GetOrGenerate { // Gets a key if it exists, or calls $fn to generate the value // and stores the value, before returning it. public function get(string $key, callable $fn): mixed; } interface Clear { public function clear(string $key): void; }