Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:108409 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 3890 invoked from network); 6 Feb 2020 13:22:40 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 6 Feb 2020 13:22:40 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 424061804D1 for ; Thu, 6 Feb 2020 03:35:19 -0800 (PST) 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-f67.google.com (mail-lf1-f67.google.com [209.85.167.67]) (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 ; Thu, 6 Feb 2020 03:35:18 -0800 (PST) Received: by mail-lf1-f67.google.com with SMTP id f24so3857327lfh.3 for ; Thu, 06 Feb 2020 03:35:18 -0800 (PST) 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=pnM/JhX0u9GVoIT/fQUXV/GFyKXB81dh1pduOm5HgdE=; b=NrOUCMzueMQnP3bOvShu0gBEXJtO2kI/ag1/F41ylLbyxuZQKvGQ12Oe9/PkTlLrHf zteVeSwjEhFXSgZtT8YLF77p40M7WOjwXIDnd/NESanlWnd6o4lW4XZU6mGRzkSvf8c6 s4XMyPbimQoHx2KvkjI0P8/H6WeA7HMSgjAayXQZceJGvOuq+7Bb2fj+oSA+mVqmR10B KhQiGp7pb72ar9998AoUrVO4p3sQ4W5ja3UAOUyGIN33XLlLNKVdDHj7DoU7/l81RIEa wthBgA8RtflLfOCiBKcNOI/XG4RWzXHJuJuo3lhmlmsMerctxwqKv/eoiQ+EejUFSY5a JDAg== 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=pnM/JhX0u9GVoIT/fQUXV/GFyKXB81dh1pduOm5HgdE=; b=a0HYDYAdk0KDNR0esJoyKLBWuho2iT4RGalQQrvKqKIx1GuAcrUan5aoiGhO2rPtlT 3mWKw4oDt5RaFG4yY3p5t9qLLNAW52o/teVwsOydqp8HBGSCwua100l8AUDQ71cFe9MF tVjQt4vLAP/ePK/WfCCpZpPeUF41r9YV2paIhhlI3UBRrlK9N97LC/aUgqloXQgSSNv0 VLkXOTbEM7+3u1L9yfv/3BqNniy4wxBpe65J40+O+y4993Kw8XgKf56wjwldRhOuHtRQ 5gmcVrFHcOmvQg5T74IeGH6UtvM4zKlnWhbwyTs2rS5EMgPuj6ojjUBCaycn0HbJ6FgX 28Hg== X-Gm-Message-State: APjAAAXFbVBwmeW/+0qAtyPOmyr8rN5ejj8F7kHrvubaeexGnfpjZUqK ot1lUJj1DyBpeAdqZ5p75uUwyZV67PKl33W0Ys4= X-Google-Smtp-Source: APXvYqwWOAuLzoHwDwL7G/N28CnVE8VcOZHq93J5WtMaBizAhaNX6GbSXLQ4ajLhNfS0P5x0d3iT7H76MuL36y0GtO0= X-Received: by 2002:ac2:43af:: with SMTP id t15mr1619777lfl.154.1580988917465; Thu, 06 Feb 2020 03:35:17 -0800 (PST) MIME-Version: 1.0 References: In-Reply-To: Date: Thu, 6 Feb 2020 12:35:01 +0100 Message-ID: To: tyson andre Cc: "internals@lists.php.net" Content-Type: multipart/alternative; boundary="000000000000d1c6a0059de6aac1" Subject: Re: [PHP-DEV] Planning an RFC to allow calls to global functions in constant expressions From: nikita.ppv@gmail.com (Nikita Popov) --000000000000d1c6a0059de6aac1 Content-Type: text/plain; charset="UTF-8" On Sun, Feb 2, 2020 at 12:00 AM tyson andre wrote: > > Hi internals, > > I have a working implementation for calling global functions in constant > expressions at https://github.com/php/php-src/pull/5139 > (see PR description for more details, see tests for how edge cases get > resolved) > > If there was interest, and no implementation or process blockers I was > unaware of, I was planning to set up an RFC with votes along these lines: > > 1. (Primary) Yes/no for supporting calls to global functions, with or > without the below limitation (requires 2/3 majority) > 2. (Secondary vote requiring 2/3 majority to allow calls to all global > functions) Support calls to any user-defined or internal global functions, > not just unambiguously resolved calls to the deterministic, side effect > free ones that are guaranteed to be installed in core extensions. > > Alternately, have a first vote on allowing a small subset of global > functions calls, then if that passes, start a second vote on allowing all > global functions. > > For example, allow `\count()`, `\strlen()`, `\array_merge()`, and > `\in_array()`, > but don't allow functions such as > `\strtolower()` (different in Turkish locale), > \sprintf() (Depends on locale and `ini_get('precision')`, but so does > `(string)EXPR`), > `json_encode()` (The `json` extension can be disabled), > or calls which aren't unambiguously resolved with `\` or `use function`. > I'll assemble the list when writing the RFC. > > https://github.com/phan/phan/blob/2.4.8/src/Phan/Plugin/Internal/UseReturnValuePlugin.php#L190 > has a list of candidate functions (non-deterministic ones such as rand() > will be excluded). > > I mentioned this earlier in https://externals.io/message/108238#108238 > The use case I have in mind is different from what was mentioned there, > and this is *just* adding supports for function calls by name, not any > other expressions (variables, properties, methods, etc) > > Motivation for the voting structure: There are many opinions on what a > constant *should* be used for, e.g. one opinion is > https://externals.io/message/108238#107992 > > > > Off the top of my head, I can think of three types of things that you > might call "constants": > > > > 1. A value that will never change, and you just want to give a name to. > For instance, MINUTES_IN_HOUR=60 > > 2. A value set at compile-time, to hard-code a particular condition. For > instance, DEBUG=false > > 3. A value which is set at run-time, but happens not to change during > the course of the application, so should not be over-written. > > > > PHP's constants are designed primarily to be type 1 - they are literal > > values, hard-coded in the source. Unlike C, there is no standard > > pre-processor for PHP, so type 2 is rarer, but it's possible to > > implement by manipulating the source file before deployment, or even > > when running the autoloader. > Hey Tyson, As you've already realized, the main problem here is the behavior for functions that have side-effects or state. Currently we mostly get away with the illusion that it doesn't matter when exactly constexpr initializers are evaluated. Apart from the error location and (admittedly quite a few) other details, you ostensibly can't distinguish whether the expression is going to evaluated on declaration, on first access or on each access. I'm not a big fan of whitelisting functions, especially as this runs into the name resolution issue (you suggest that essentially the use of fully qualified/imported names will be forced -- unlike everywhere else in PHP), and because I've seen this "mark all the functions const/constexpr" race play out one too many times in other languages, which have a much stronger motivation for it than we do. If we want to expand the allowed operations inside constexpr initializers, I think this needs to start by considering precise evaluation semantics in the places where it matters. Those are primarily initializers for function parameters and non-static properties, because both of these have a reasonable expectation of evaluation at each use. I think the best way to approach those two may well be to relax the constexpr restrictions on them entirely (allowing say "public Foo $prop = new Foo()", something people want anyway) and make sure that things are evaluated on each access (unless they can be pre-evaluated without affecting behavior, of course). For the remaining cases (constant, class constant and static property initializers) we can probably get away with the current semantics, which is evaluation on first access, with a very broad definition of what "access" means. Regards, Nikita --000000000000d1c6a0059de6aac1--