Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:108015 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 88752 invoked from network); 6 Jan 2020 23:54:37 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 6 Jan 2020 23:54:37 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id AAF651804D1 for ; Mon, 6 Jan 2020 13:59:36 -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, 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-wr1-f53.google.com (mail-wr1-f53.google.com [209.85.221.53]) (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 ; Mon, 6 Jan 2020 13:59:36 -0800 (PST) Received: by mail-wr1-f53.google.com with SMTP id g17so51562975wro.2 for ; Mon, 06 Jan 2020 13:59:36 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=subject:to:references:from:message-id:date:user-agent:mime-version :in-reply-to:content-transfer-encoding:content-language; bh=Giqzq5e/dKuo7NXXB5HhCgiezJVKgCBnc45DXbbLzwE=; b=TnwxxsQZwToK/AQchqd5a0KDmkJAaYlzymUO8cyaVZ6/hybYP2qOoFVYsA6IqRpmfT Jo3KgZe+OHFVluvDjeAh+WNPSGv2DBgEy+3Y240lzqQmdo95am3cwG9FwPBOsYxkHeaR wARHK7MdsL/5rSnmO/w0XgWFOrtlYDx9xzeHLa3otn2hx3ZIBTB3dlyemRXTCfVtk59B RO9M0ZI7k9RmEQIx5mH0e45pITpdMm3WIk5qeOAGCwej3XMJ5pB28DE3ZUM9q+dAEGuy PGg9bRuQ/0c7Sz6Lc7Mj67I+qF50funI1DJBV2DE23nPbiA2eZ4OHKJWu1hr91w6DfaC 78HQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-transfer-encoding :content-language; bh=Giqzq5e/dKuo7NXXB5HhCgiezJVKgCBnc45DXbbLzwE=; b=cysILJ665EWTiu7k3pyuB5S7Y0nkDRZgO7gPrXDObKJO66/XWwOFf9kjWXpI5M7uiL gCpJ6/wSePb1qkeUnJsFq7M1xe14qRIgH0TFsVaXtp6+w/DXrxJMw3t6iuJGN2RQtyot TOlWKg3cwwNL0kJ4G9pAhSWxCXAgaZmCNnKCBvsu9oaTqDK8ANMIMKLKyGZDG64F35Km abeV9VlFbqJWgb5mN2tQ6XddCWSst9TDy/GEXjXTSbWteFH2r5I+8+qjJqjTOhfX2fdR uy6qkahWxTuxiGMb3IJjZFL4bQ/ynLk/HcZ+srcHxOKS0oIq5x0s+4Nu7X4dlOnxT/Fd FQig== X-Gm-Message-State: APjAAAVoMk8kqt/Ljsp0B0PO209hx0eNZFZEeE044X1/IONZ8tBrKUNG IRvQC1susoluoJ83rLVPkvrH557Q X-Google-Smtp-Source: APXvYqz9ns1qJMO/GDCeQDBeaawWAqc9A0Fq79sDEza5AB6Z//gGA318LI0ESPHBEDjikCJzgcUjdA== X-Received: by 2002:adf:dd4d:: with SMTP id u13mr106932614wrm.394.1578347973918; Mon, 06 Jan 2020 13:59:33 -0800 (PST) Received: from [192.168.0.14] (cpc84253-brig22-2-0-cust114.3-3.cable.virginm.net. [81.108.141.115]) by smtp.googlemail.com with ESMTPSA id f127sm24046690wma.4.2020.01.06.13.59.32 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 06 Jan 2020 13:59:33 -0800 (PST) To: internals@lists.php.net 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> Message-ID: <6f20bda1-eff6-631d-915f-d6bb149ee666@gmail.com> Date: Mon, 6 Jan 2020 21:59:29 +0000 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:68.0) Gecko/20100101 Thunderbird/68.3.1 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Content-Language: en-GB Subject: Re: [PHP-DEV] Initializing constants once, with code? From: rowan.collins@gmail.com (Rowan Tommins) On 05/01/2020 21:53, Mike Schinkel wrote: > Yet you called my list of URLs enums, and they are not at all arbitrary and absolutely want to change. I apologise - I took a guess without context for how those constants would be used, but apparently they're something rather different. > I take it you have never used Pantheon hosting then? You create a named environment to match a Git branch. I'm still struggling to understand why you need multiple constants, all mutable based on some other dimension. If the ultimate goal is to know the name and branch of the *current* environment, how do the constants help? It seems on the face of it like the constants have outlived their usefulness, and need to be replaced by a lookup table of some kind. > What is "better" in this context is one's opinion. You might not find > it beneficial, but I would. Agreed. I actually said the same in one draft reply, but maybe deleted it while editing down. >> "Constants are defined at compile-time" is a status quo in the same sense as "variables can be assigned to" is a status quo - you could certainly design a language differently, but it's not just something that happened by accident, it's a design decision. > It was a design decision in that maybe it did not occur to them that it would be useful; IOW a design by omission. We'll just have to agree to disagree here. I stand by the assertion that "compile-time constants" are a well-defined feature, whose restrictions are part of their definition and purpose. > Ruby has the .replace method for constants and can thus assign at runtime: > ========= > https://stackoverflow.com/a/6712438/102699 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. > C++ has const member functions (not exactly the same, but similar): > ========= > https://www.linuxtopia.org/online_books/programming_books/thinking_in_c++/Chapter08_014.html Unless I'm missing something, this isn't really related to anything we've been discussing, it just happens to use the keyword "const". > Python adds a final qualifier to turn variables into constants. Thus is supports initializing constants: > ========= > https://stackoverflow.com/a/47821212/102699 > http://code.activestate.com/recipes/65207-constants-in-python/ 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. > Javascript can assign constants at runtime: > ========= > fn = function() { return "World"; }; > const who = fn(); > alert( "Hello " + who ); This is a more interesting case; some properties to ponder: - implemented as a special kind of variable (e.g. they have the same scope rules and syntax as "let" variables) - can be global or block-scoped, but not a property of an object - cannot be pre-declared before they are assigned, or automatically initialised on first reference - can contain any value, including mutable objects > Java creates class constants with `public static final` which can be initialized with code: > ========= > https://www.javaworld.com/article/2076481/use-constant-types-for-safer-and-cleaner-code.html Another interesting case: - implemented as a special kind of variable - can contain any value, including mutable objects - will raise an error if the compiler cannot prove there is exactly one assignment; i.e. these are not purely run-time constructs like PHP's define() constants - can be static members of a class, and include an inline initializer - can be static members of a class and have no inline initializer, in which case they *must* be initialized using a "static initializer block" which will be run the first time *the class* is referenced at run time (a bit like substituting the value during autoloading in PHP) - can be instance fields, and must be initialised inline, or in every possible constructor - can be block-scoped variables, and must be initialised before first use The interesting thing here is that the constants are initialised the same way as any other variable, not using any special on-demand code. Because of the language's design, the compiler is able to prove that they are assigned exactly once. That proof is probably a lot harder in PHP, and the check would probably be punted to run-time. The biggest sticking point in my mind is your insistence that they share syntax with constants, rather than variables. This means they can only be used in static class or namespace context, not against an instance. 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. That's likely to cause confusion for both humans and tools written based on the current concept that a constant can always be computed at compile-time. >> It's a limitation in the very basic sense that it limits what you can do. You can't write this, for instance: >> >> class API { >> private $config; >> public function __construct($config) { >> $this->config = $config; >> } >> >> const URL { >> return $this->config->getValue('API_URL'); >> } >> } > But you could do this: > > class Api { > const URL:string { > return Config::get()->api_url; > } > } The difference is that a Java-style "final variable" can have a single value *per instance*, so this is valid: class API { private final $URL; public function __construct($config) { $this->URL = $this->config->getValue('API_URL'); } } >> I'm just looking for solutions to your use case, which as I understand it is values which change rarely based on configuration. > I honestly do appreciate it. You are generally very good about that kind of thing. I would be interested to hear more about why you think pre-processing doesn't suit your use case. It seems like a good fit to me: - naturally fits with code expecting compile-time constants - no run-time overhead if done as part of deployment - can be implemented using succinct syntax, rather than run-time initialisation code Regards, -- Rowan Tommins (né Collins) [IMSoP]