Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:107305 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 7631 invoked from network); 24 Sep 2019 01:59:21 -0000 Received: from unknown (HELO php-smtp3.php.net) (208.43.231.12) by pb1.pair.com with SMTP; 24 Sep 2019 01:59:21 -0000 Received: from php-smtp3.php.net (localhost [127.0.0.1]) by php-smtp3.php.net (Postfix) with ESMTP id 821442CFF37 for ; Mon, 23 Sep 2019 16:38:06 -0700 (PDT) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on php-smtp3.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,SPF_HELO_NONE autolearn=no autolearn_force=no version=3.4.2 X-Spam-ASN: AS3215 2.6.0.0/16 X-Spam-Virus: No Received: from mail-qk1-x72d.google.com (mail-qk1-x72d.google.com [IPv6:2607:f8b0:4864:20::72d]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by php-smtp3.php.net (Postfix) with ESMTPS for ; Mon, 23 Sep 2019 16:38:05 -0700 (PDT) Received: by mail-qk1-x72d.google.com with SMTP id u184so17397961qkd.4 for ; Mon, 23 Sep 2019 16:38:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=dqxtech-net.20150623.gappssmtp.com; s=20150623; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc:content-transfer-encoding; bh=IQkwKVg4N2yeby6FVuZTeXyw5y1SB0ty+22fNePQtdM=; b=odkZrNHDrGhwmNlzXoX2/zXGagrPewnUXdL26d3YytPmZL5RObPn9d8KnZw1OHF1Us 0bBcApF0K53akQISM9ldz6hFHUAcpczHAHq7adJRtqSq6rjacqzlfVLSFDtgT5qaWVMu 2rexgcm0d54lc9ZtsqMtnb2XHd9jppGrtlk1GuCLSyfMq/eKBMBnDibTN6RIYbHNUarN rrrvvUy3mdNb0V0bGB8EzunSQb7jjJ2XFWwDvORxMVm7vL9org+l3UKBobVSJoStP/DE XQQeH9KDlJkr9yPlF8ovSBIkg0S85bPRyOmyuGRzDda595huLVNoU29oxzpTzrQkY6KQ kojg== 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:content-transfer-encoding; bh=IQkwKVg4N2yeby6FVuZTeXyw5y1SB0ty+22fNePQtdM=; b=KuOKvWkePIEAK/A7EYUaPhh6dzDKzItnCXnabBz1uSZZVps4m7aLyav2kb+jb43TSG dCYXhYyr1by7UFYPWJw4jwg1yco+99z0h5zzSJbCV1EjLDnATsezbwzHoCFU8xjWec9u Axjjv9oMXSs45hKZjs495JZLgw5ufi7iRj8mPeCew7XouA13xTtrluZQnReTF9M9iv9d L/JU2lUEYrVxKsrgVTxcDfIc9rO7nSfQ9SbMvaGhaLdh1iwQOxq2a4LUGwRXoj+jCDe9 Yzj1DvCoOZxxKjnZPBb5dZrvpFC8iDcfcNa2dNP3cDLlzJO24PkGBRm6zULO7rjL4zM7 OeBg== X-Gm-Message-State: APjAAAVq1Y+2/QGoXsRFe37GIzkrCJgUjhSHh1ZEqYIbMi89VF6ImtfM LHJP2yb1JOfdphKk3y82/cXUWadtoEI= X-Google-Smtp-Source: APXvYqwIYy2s83YePTQjLYUJbXGzhv+sO/psjmWDyUczy6UE6CXjSbE0s6VDB9xbvZUeLKer3ZS3Ng== X-Received: by 2002:a37:9dd2:: with SMTP id g201mr497176qke.55.1569281885001; Mon, 23 Sep 2019 16:38:05 -0700 (PDT) Received: from mail-qk1-f174.google.com (mail-qk1-f174.google.com. [209.85.222.174]) by smtp.googlemail.com with ESMTPSA id k54sm7810777qtf.28.2019.09.23.16.38.04 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 23 Sep 2019 16:38:04 -0700 (PDT) Received: by mail-qk1-f174.google.com with SMTP id 201so17319094qkd.13 for ; Mon, 23 Sep 2019 16:38:04 -0700 (PDT) X-Received: by 2002:a37:a790:: with SMTP id q138mr470651qke.383.1569281881871; Mon, 23 Sep 2019 16:38:01 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: Date: Tue, 24 Sep 2019 01:37:50 +0200 X-Gmail-Original-Message-ID: Message-ID: To: Benjamin Morel Cc: Nikita Popov , PHP internals Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Envelope-From: Subject: Re: [PHP-DEV] Re: [RFC] Union Types v2 From: andreas@dqxtech.net (Andreas Hennings) To have any information content, a variable (or return value, or parameter) needs to have more than one possible value. If one of those values is TRUE, the most natural alternative value would be FALSE. But should this really be baked into the language? Should really "try to be smart" here? Isn't it better to aim for completeness and consistency, and provide a "round" developer experience with the least amount of surprise? The same could be asked about other restrictions, e.g. false|null. Ideally we should have a type system with the properties of a mathematical space of some sort. Artificial restrictions would ruin this. It won't be perfect, because the different types are not "symmetric". But we can at least try to make it as consistent as possible. Some use cases I can think of: ## Use case: true[] assoc I like to use true[] for map-like associative arrays. So, $map[$key] =3D true; For each key, the array either has the value TRUE, or no value at all. No need to store false values. An extended use case might be a (tree =3D true|tree[]), where each leaf would have the value true. Does this mean we need true for parameters and return types? It will be rare. Especially in the first case of a simple true[], there is no point returning the value in a variable, if we not also allow FALSE for "not found". ## Use case: Generics However, what if the code is written in a generic way? E.g. if PHP gets native generics one day, or some userland generics library based on code generation. For an iterator over true[], the return value for ->current() would be "true|null". (I just tried, it is null and not false, see https://3v4l.org/PvWWl). For a generic method receiving values from the array, the parameter type would be "true". It would be really disappointing if a tool that attempts to give us generics would have to work around arbitrary limitations of the typing system. ## Use case: Variance Imagine a base class or interface method which returns boolean for success / failure. We extend this method, and our implementation is always successful, so we will always return true. We can indicate this in the type hint. This indicates that calling code does not need to check the return value, it can simply assume that it was successful. interface Operation { function run(): bool } interface SafeOperation extends Operation { function run(): true // always successful. } ## Use case: Code generation and reflection tools I would say that for any automated tool, special cases of disallowed types make things more complicated. This could be tools for code generation, parsing, or some kind of "type reflection" with type arithmetics. ## Use case: Legacy code Finally, in some cases it is irrelevant whether the combination of types makes sense or not. We simply want to type-harden legacy code. On Mon, 23 Sep 2019 at 22:15, Benjamin Morel wro= te: > > Hi Nikita, > > Thank you for your work on this, I look forward to being able to use unio= n > types! > > The one thing that bothers me a bit is introducing yet another > inconsistency by supporting false and not true as a type. Sure, I do get > the need for false as a valid type for historical reasons, but at the sam= e > time I thought it would be interesting to see if true was being used as > well in the wild, before closing the door on it. > > Therefore I reviewed all Composer packages with > 1 million downloads (12= 11 > packages total), and here are the results: > > *31 packages > > use at least one @var, @param or @return containing true as a type.* > > - there are many illegitimate use cases, such as @return true > > , @return bool|true > , > @return true|false > , > or even @return bool|true|false > > - there are, however, quite a few potentially legitimate use cases. Among > others: > > - @return true|WP_Error > > (*johnpbloch/wordpress-core*) : "True if the JSON data was passed or no > JSON data was provided, WP_Error if invalid JSON was passed." > - @return true|string > > (*johnpbloch/wordpress-core*) : "Returns true on success, or drop-in fil= e > to include." > - @return string|true > > (*php/di*) : True if compilable, string explaining why if not > - @return string|true > > (*zendframework/zend-authentication*) : True if successfull, error messa= ge > if not > - @param int|true > > (*yiisoft/yii2*) : "Use 0 to indicate that..., Use a negative number to > indicate that..., Use boolean `true` to indicate that ..." > - @param callable|resource|string|true|null > > (*symfony/symfony*) : "A line dumper callable, an opened stream, an outpu= t > path or true to return the dump" > > Full list here > > . > > So although true as a type does not have the same historical background a= s > false, it does seem that it's being used by enough packages to be worth > considering; what do you think? > > =E2=80=94 Benjamin