Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:108022 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 19920 invoked from network); 7 Jan 2020 12:10:16 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 7 Jan 2020 12:10:16 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 0E60C1804A8 for ; Tue, 7 Jan 2020 02:15:24 -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-io1-f45.google.com (mail-io1-f45.google.com [209.85.166.45]) (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 ; Tue, 7 Jan 2020 02:15:23 -0800 (PST) Received: by mail-io1-f45.google.com with SMTP id i11so51962869ioi.12 for ; Tue, 07 Jan 2020 02:15:23 -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; bh=W/MhuUaowhxdK7fniN5e5U3bd2KQfzVJqcETN1FW4pM=; b=WmrqmgMZRymmECgvKXEO3ekfXN3PMBAu7LRoCB9zn1SbeURrZoCqxWHnBzgSFQri4i YA2TLGo/ADpl9L38T5z916rv4DE7ucbAhAvIlauaiW6r0SHxrUz/Pge/riMeSRlzifsV Ic4yacoKsgM2iRGmy5ZQfuRv8P+gRC3fWZEpfqZVzLYEjBOpnIfK/zRPWgWdSAcuQ0gs ky3jhM7edoIFtnOO43s3l7q6jnLpPjORwdWRunBEz9oNxYqxdE4mRdRvabXQV7+Yp05N MLdw0vbpxA2NiNcmOujsPbdHWgL0dKA00V99vxo8c5kNb0x2B0tFG/zOWcWncJhN+NeZ uwqw== 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; bh=W/MhuUaowhxdK7fniN5e5U3bd2KQfzVJqcETN1FW4pM=; b=HY2hvYUglu3biZabnSjOAEMXzF+6GJqZ6kroIXrW4/nsPAh3iJQsLFrLQ5dcu18O4T T8PU+WKLg5WWf0EpfDeJe2C2PHPyWbG1F1pP+SBlZi8qC8QD4kTOLNYaJ2OFPJ7phMUn redfon72JXkuNCNYS1qJVXmN8Us9Y13zEbm3niRBW/5F1JTh2EgvVN9Hk45SQ0IzkojK R3bLkEQ7nn1Pp438xydsGUAQkUuHUnOL+gmKiNpRtDuf8Pz3SV4SWEo1Wg8pNIAXiBT/ BeeFqoUgi/r07NwVoCaTtpb/F9CD2SyvA3EjxJb/K8c2CXZ9XBUVX5JaYhMWC+LcS9LZ kqNQ== X-Gm-Message-State: APjAAAWTp07XNfx+Nzyv7gXIoz8IMBeNcVzaqKiavqdcdOjHnk6lZ9v4 ZhLgCG4qHRYSt6abpiKPlq+px5+MMLaBA2cM/HNsyLr3 X-Google-Smtp-Source: APXvYqxWbwqO91NScJxm4QkHos+kOFWTQBU/RUD3RR0MbYtJUKxdI5Lnut9zkZ0uSTWB+fg+78tSwAkNgjht5xVZzf8= X-Received: by 2002:a5e:9902:: with SMTP id t2mr69655798ioj.120.1578392121090; Tue, 07 Jan 2020 02:15:21 -0800 (PST) MIME-Version: 1.0 References: <5e0d723f.1c69fb81.e2ae8.24e2SMTPIN_ADDED_MISSING@mx.google.com> <74F2DBFC-E63C-428C-A37F-2D0CEE15AD0F@newclarity.net> <53556dfb-44ce-f902-204c-9a7da9484a61@gmail.com> <65567C7C-CF0F-4562-8943-F1F302134B07@newclarity.net> <6f20bda1-eff6-631d-915f-d6bb149ee666@gmail.com> <93BA4B49-9D9A-4A41-83B3-8EC2564A70BF@newclarity.net> In-Reply-To: <93BA4B49-9D9A-4A41-83B3-8EC2564A70BF@newclarity.net> Date: Tue, 7 Jan 2020 10:15:09 +0000 Message-ID: To: PHP internals Content-Type: multipart/alternative; boundary="000000000000b1a76e059b8a0d73" Subject: Re: [PHP-DEV] Initializing constants once, with code? From: rowan.collins@gmail.com (Rowan Tommins) --000000000000b1a76e059b8a0d73 Content-Type: text/plain; charset="UTF-8" On Tue, 7 Jan 2020 at 01:13, Mike Schinkel wrote: > At least two come to mind: > > 1. Guard clauses for code you only want to run in one environment and not > another. > 2. Common code that is used by different websites. > It seems to me that there are two different concerns there: - An enumerated set of environments that never changes, which code can associate logic and configuration with. That maps well to PHP's constants, and would be even better with an enum type. - A mapping from that set of environments to a set of branches, which is initialised at run-time based on environment information. That sounds like an associative array with the environments as keys. So at its simplest, I would write something like this: class Environments { const PRODUCTION = 4; const STAGING = 3; const TESTING = 2; const DEVELOPMENT = 1; public static $branches = [ self::PRODUCTION => 'master', self:: STAGING = 'stage', self:: TESTING = 'test', self:: DEVELOPMENT = 'dev', ]; } That way, you can write code like "if ( $currentEnvironment == Environments::PRODUCTION )" without caring about the complexity of mapping branches to environments. You can also associate other data with each environment - maybe there's a database name for each environment as well, for instance. > That method is not actually a feature of constants, its abusing the fact > that everything is an object, so the *value* of a constant might still be a > mutable object. It's an interesting "cheat", but it's not really a > deliberate language feature. > > > The .replace is not a deliberate language feature? > It's not a feature of constants, it's a feature of strings and arrays, because they are implemented as objects. The same trick would be possible in PHP if constants could have objects as values: const FOO = new DateTime('today'); self::FOO->modify('+1 day'); The constant FOO hasn't changed value, but the object it points at has been mutated. In Java, the same would be possible with an Array, but not a String, because although they're objects, strings are designed as immutable. Those links seem to say that Python doesn't have constants *at all*, but > you can emulate them in various ways. As such, you can give them pretty > much whatever behaviour you like, since you're defining the language > feature from scratch. > > > Yes. IOW, Python did not feel there was a need for a compile-time constant. > Or maybe everybody really wishes it had them, but nobody's come up with an implementation that fits into the language design? > I can already use static variables, and the immutability is not that > important to me. > > It's the desire to be able to start as statically declared constants and > evolve later to dynamically initialized. > If we take these two statements really literally, you can do everything you want already: start with a static variable which you don't change (but isn't guaranteed immutable), then evolve later to initialise that variable dynamically. Maybe your use case would be solved by making the syntaxes for accessing constants and static variables interchangeable, so that Foo::BAR and Foo::$BAR could reference either? Unfortunately, it's currently possible for both of those to exist at once, so that's probably not going to work. > As for immutable variables, I see those as very useful to, but I think > their use-cases are orthogonal to the use-case I was trying to address. > Then all the JS and Java examples aren't going to help your argument, because those are most definitely immutable variables, not compile-time constants extended with initialisation syntax. > It also means *widening* the meaning of a construct, rather than > *narrowing* it: the "final" keyword in Java doesn't let variables do > anything new, it just restricts them; your proposed constant initialization > would allow constants to act in new ways, including holding complex, > mutable types. > > > But isn't that often the point of new features; to allow for doing things > in new ways? > Sometimes, yes. Sometimes it's to provide safety, or elegance of expression, without adding any new behaviour at all. My point was that more assumptions will break if you widen the meaning of "constant" than if some variables are marked immutable. > I often chuckle when I hear that something might cause confusion as an > argument against adding to PHP because it makes me think of PHP generators, > generator return expressions and Generator delegation! > > I assert that if we can add generators (and in the future, generics!) then > most anything we could add is going to be less confusing. :-) > For the record, I think generators are a really neat feature, but absolutely hate that they are declared with the "function" keyword, and hate that they reuse the "return" keyword for "set final value". So, yes, that's a good example of something that breaks people's expectations of what keywords mean, and I think that's a bad thing. > and tools written based on the current concept that a constant can always > be computed at compile-time. > > > My assumption is that the tool would simply be updated to recognize which > constants would be initialized at runtime. > I'm not saying it's impossible to account for it, I'm just saying there may be a lot of tools out there which would need to be updated. Saying "simply" doesn't make it so! > The difference is that a Java-style "final variable" can have a single > value *per instance*, > > > I cannot think of anything conceptual that would keep us from having > constants per instance, but I don't see a strong need for is so I did not > propose it. > Well, we'd need a new syntax, for a start, since $foo->bar already accesses a property. > I would be interested to hear more about why you think pre-processing > doesn't suit your use case. > > > When I think of pre-processor, I think of textual substitution. > I was thinking much more abstractly: some code of some sort that runs as a separate build step, and produces some kind of output that can be referenced cheaply at run-time. In particular, I was imagining the pre-processor being fully aware of the language's syntax, and operating at the AST level. You could view it as an extension of compiler optimisations: explicitly saying "run this before you even deploy to the server, the result will never change". The output to PHP is necessary for the same reason client-side languages are transpiled to JavaScript - it's the language spoken by the target run-time. If we could treat OpCodes as a stable target, like .NET CLI, or Java bytecode, it could target that instead, but it wouldn't actually make much difference to the operation of the pre-processor. There is of course a side-effect that the resulting PHP code can be read by a human, making it easier to debug. Regards, -- Rowan Tommins [IMSoP] --000000000000b1a76e059b8a0d73--