Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:108014 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 83393 invoked from network); 6 Jan 2020 23:19:31 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 6 Jan 2020 23:19:31 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id A70281804D1 for ; Mon, 6 Jan 2020 13:24:30 -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.6 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_LOW,SPF_HELO_PASS,SPF_NONE autolearn=no autolearn_force=no version=3.4.2 X-Spam-ASN: AS11403 66.111.4.0/24 X-Spam-Virus: No X-Envelope-From: Received: from out5-smtp.messagingengine.com (out5-smtp.messagingengine.com [66.111.4.29]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Mon, 6 Jan 2020 13:24:29 -0800 (PST) Received: from compute7.internal (compute7.nyi.internal [10.202.2.47]) by mailout.nyi.internal (Postfix) with ESMTP id A577B22011 for ; Mon, 6 Jan 2020 16:24:28 -0500 (EST) Received: from imap26 ([10.202.2.76]) by compute7.internal (MEProxy); Mon, 06 Jan 2020 16:24:28 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to:x-me-proxy :x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm1; bh=tXryGR 39eeBqdxdlOV4PlhFgOIWZet/qVZw47+OlvT4=; b=ADcdetVIbdbAJ0p+E2fo2q TUpVM5+K6/NCcZxa4veG3ogz2Mk9s0mTSQDUizDUrrkLPFbPGU6YGhpHg0z/yqBn 9RPQS2LTFptLRs84S6TUNDdZ//95j4WQ7fDZZNG+KA+UuekvpR4BCG26bWjzPmTh 55ABx7IaXNcd3+B29aO0bvp4dC/Jc6j50JCt6a/x5bFXvxIEg+ceGu6uAI4QwTcN BT+XPXyrLgRnAUYP1xuyfuuc01pI3D0/tQ18/LMu8zWGjcc9TspyGjk7Cm3oezfG +4ht9lQUbSf8J+7+9nXxmOnF/GrcTlHquBFFUvedrS8jT25ybC4/rUq6ppxnhtUQ == X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedufedrvdehtddgudeglecutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfgh necuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd enucfjughrpefofgggkfgjfhffhffvufgtsehttdertderredtnecuhfhrohhmpedfnfgr rhhrhicuifgrrhhfihgvlhgufdcuoehlrghrrhihsehgrghrfhhivghlughtvggthhdrtg homheqnecuffhomhgrihhnpeifihhkihhpvgguihgrrdhorhhgpdgvgigrmhhplhgvrdgt ohhmnecurfgrrhgrmhepmhgrihhlfhhrohhmpehlrghrrhihsehgrghrfhhivghlughtvg gthhdrtghomhenucevlhhushhtvghrufhiiigvpedt X-ME-Proxy: Received: by mailuser.nyi.internal (Postfix, from userid 501) id 317A714200A2; Mon, 6 Jan 2020 16:24:28 -0500 (EST) X-Mailer: MessagingEngine.com Webmail Interface User-Agent: Cyrus-JMAP/3.1.7-731-g1812a7f-fmstable-20200106v2 Mime-Version: 1.0 Message-ID: In-Reply-To: <54CAFCD7-2B99-4BA4-8A5F-3D7EBC9D810B@newclarity.net> References: <5e0d723f.1c69fb81.e2ae8.24e2SMTPIN_ADDED_MISSING@mx.google.com> <74F2DBFC-E63C-428C-A37F-2D0CEE15AD0F@newclarity.net> <54CAFCD7-2B99-4BA4-8A5F-3D7EBC9D810B@newclarity.net> Date: Mon, 06 Jan 2020 15:24:07 -0600 To: "php internals" Content-Type: text/plain Subject: Re: [PHP-DEV] Initializing constants once, with code? From: larry@garfieldtech.com ("Larry Garfield") On Mon, Jan 6, 2020, at 2:28 PM, Mike Schinkel wrote: > > On Jan 6, 2020, at 1:07 PM, Larry Garfield wrote: *snip* > From: https://en.wikipedia.org/wiki/Status_quo_bias > > But if I mischaracterized your objections I apologize. I am not anti-change for anti-change's sake. Since I presume from earlier comments that you're familiar with my background in Drupal I think that is sufficient evidence that I am not against change as a concept. :-) Let us move on. > > It violates pure functions, and pure functions are how you get any semblance of predictability in your code. I do not have the time or inclination to go through all the details of that here; you can find ample resources for that yourself. > > I am very familiar with pure functions, you don't need to go through > the detail with me. > > That said, class methods in PHP are not pure functions and PHP has not > embraced pure functions so I am not sure why you are using this your > rational other than maybe you wish PHP was a pure-function language? > Of course if it was limited to pure functions, we'd not be able to > configuration from outside the program anyway. Yes, PHP doesn't have pure functions as an explicit thing. This makes me sad. :-) The point here is that when I call a function in PHP, I intuitively expect that it may not be pure, or may be context-sensitive. That may be desireable or not in context, but the () indicate "code will run, and code may do weird stuff". When I see a constant, I expect it to be, well, constant, deterministic, and have a small fixed performance impact. (In the case of `const`, zero performance impact.) For example: const DEBUG_MODE = false; function foo() { if (DEBUG_MODE) { // Do stuff. } } PHP will currently (AIUI) inline the DEBUG_MODE value at compile time, notice that the code path is unreachable, and omit it from the compiled opcodes entirely. (I'm pretty sure it does that now, at least; if not, it certainly can be.) If you use a define, however: define(DEBUG_MODE, $_ENV['debug'] ?? false); function foo() { if (DEBUG_MODE) { // Do stuff. } } That optimization cannot happen. But just from looking at foo() I cannot tell which is going to happen. I view that as a negative. > > I work for Platform.sh, which has been doing environment-per-bit-branch longer than Pantheon has. > > That statement was in response to Rowan's comment, not yours. I know; I included that as a resume so that my following points would carry more experiential weight. (And because we really were doing it before Pantheon, who is a competitor of ours, so there. :-) ) > > In my experience, systems that configure themselves via constants are the worst. > > Of course they are the worst! Because you can't initialize constants > dynamically. No, it's because you cannot override them. It makes the conditional logic around defining them more complicated. Specifically, with WordPress for example, I cannot just leave WP's default config script in place and tack ours on before/after it. I have to hack theirs up and replace it with one that checks every possible source for DB configuration information and then set it once, because it cannot then be overridden. They actually *are* set dynamically with declare(). The runtime dynamism isn't the issue. In this case it's actually the immutability that causes the problem, ironically enough. :-P An example of where I can see problems: In some systems, $_GET is treated as mutable. It is, but modifying it is generally a bad idea, but people do it anyway. For instance, I've seen "clean URLs" implemented by modifying the $_GET variable and $_SERVER variable to mutate example.com/foo/bar into example.com/index.php?q=foo/bar. (Drupal 7 for instance did that.) Now suppose you have a lazy-loading "constant" that uses $_GET. If it gets called before that conversion happens in some code paths but not others, its value will be unpredicatable. It may get built before $_GET['q'] is changed or after, which would change its value. That's not something I ever expect a "constant" to do. I expect a constant to be constant from one request to another, even if it nominally isn't derived until runtime. Constants that change value are not constant. (Is this a subjective and partially emotional interpretation? Of course it is. Much of language design, like any other design, is. But I don't think my subjective view here is unique.) > > I can see a use for const variables, especially const class variables. > > I assume you mean immutable variables that still use the $, like 'let' > in Javascript? Yes. Or the static class property example with color from the Java URL you provided, which is a nice use case. > Those would definitely be very useful, but unfortunately would not > address the use-case I presented. The specific use case you presented is not one I believe PHP should support. If I have not convinced you of my position on that yet, I don't think I am going to, nor are you going to convince me of yours. > > So the more general request here is for dynamically valued constants beyond the current `declare` support. Which... I could potentially get behind. Self-memoizing functions is one way they could be implemented, if you don't mind (). (I don't.) That would also have a lot of other benefits. > > I am confused. This sounds like you are now agreeing with the need for > dynamic constants? I am thinking aloud and allowing the available options to go where they logically go. > BTW, the requirement for () means it would not address the use-case of > allow code to be evolved. > > > The caveat in both cases is dependencies. Memoizing an impure function can lead to all sorts of time-dependent silliness. The same concern applies to dynamically valued constants. If their generation code is a pure function (however expressed), then cool, that's a safe and nice feature. If it has unpredictable dependencies, though, the behavior can be equally unpredicatable. That includes depending on $_GET or env vars. > > Totally agree that people could write bad code. But there are a > thousand ways they can already write bad code. Certainly. But a good language nudges people toward writing good code, or at least not-bad code. (How hard it should nudge is a subject of much debate and is one of the reasons we have many languages.) > > (Remember, PHP has plenty of users outside of shred-nothing requests, and with FFI and preloading hopefully more of them wil get used more often.) > > Maybe there is something here I am missing? Can you present a problem > that dynamic initialization of a constant would create only a > statically defined constant in these cases. I cannot think of one, but > I will be honest and admit that does not mean there is not one. See the $_GET['q'] example above for the sort of unpredictability I am concerned about. In a long-running process the potential for such issues is higher. > > The trick is when exactly these run, because they're impure functions so whether they run at code compile time or first-access could mean a dramatic difference in their resulting value. And that is precisely why I am very, very nervous about allowing impure functions to be cached, whatever the syntax on top of them. (Constant-like or not.) > > When you say "cached," what are you thinking the lifetime would be? > And how would that really be different from a static constant? Any dynamic constant variable has a lifetime of its scope. If global, then it's the lifetime of the process. > Are you concerned that the code could fail and leave the constant in an > invalid state? That wasn't what I was thinking of, although I suppose that's also a concern. I was more thinking of the inconsistent initialization time, as in my earlier example, leading to a constant that is variable request-to-request even if it's nominally constant-once-set within a specific request. That's a very different behavioral pattern from guaranteed consistent request-to-request. IMO they should remain separate. --Larry Garfield