On Sat, Jan 4, 2020, at 3:25 PM, Mike Schinkel wrote: > > On Jan 3, 2020, at 2:52 PM, Larry Garfield <la...@garfieldtech.com> wrote: > > > > There's two broad reasons I think this is a bad idea. > > > > 1) Constants are one thing. Function calls are another. They serve > > different purposes. Trying to mutate them into one thing can only lead to > > confusion and lack of understanding about what is actually going on. > > > > 2) The approach you describe (of starting with constants everywhere and > > refactoring to method calls later)... I would never do and do not endorse. > > What you describe is basically "make globals nicer to work with", whereas I > > am 100% firmly in the camp of "if I could remove globals from the language > > entirely I would". Frankly, the use of constants for configuration is an > > anti-pattern to begin with; they should be used only for things that are > > truly constant. Honestly, I cannot recall the last time I used constants > > for anything other than giving some other compile-time value a nicer name. > > (Eg, DEFAULT_THING_VALUE or giving nice names to bit flags or something > > like that.) > > > > For configuration, my answer is frankly "put your configuration behind a > > nice configuration object from the very beginning and then you won't have > > to refactor it later; Problem solved." You can use env vars for > > configuration, and wrap those into a nice object, possibly using one of the > > many DotEnv implementations that already exist to make them nicer to work > > with in development. That is superior in basically every conceivable way > > to semi-mutable globals passing themselves off as pseudo-constants. > > > > I *would* love to see property accessors come back, which would have a side > > effect of making what you describe a little easier, but at no point is it > > pretending to be a compile time value when it isn't. > > > > --Larry Garfield > > <sigh> So much to unpack here, but I will just hit the most important points.
*snip* > Symfony — which many PHP developers hold in high regard including > Drupal developers — uses constants: Just an FYI: I assume you mention Drupal specifically here because of my history with the project. What Drupal developers hold in high regard matters not even 0% for me at this point; "Drupal does it" is not an argument that will carry any weight with me. *snip* > I think this analysis proves many PHP developers do use constants in > ways you claim you would never. IOW, the use-cases I am trying to > address exist to a significant degree in the wild. > > Further I believe I have made the case that there would be significant > value in allowing developers who previously used constants because of > prior lack of skill or too-tight timelines to be able to evolve their > code to initialize their constants with code instead of forcing their > users to change their code or worse. > > -Mike I think you are overstating my case. I am not arguing that one should never use constants. In fact, a majority of the examples you cite I would say are reasonable uses of constants, at least in concept. (I cannot speak to the particulars of the individual code bases.) I am saying that the behavior of a constant is that it is... constant. A proper constant is evaluated at compile time and appears as a literal in the final runtime code, with no dereferencing. AIUI, `const` in PHP does exactly that, in contrast to `define`. That is fundamentally conceptually incompatible with a value that is derived at runtime and happens to use constant-style syntax. I am firmly opposed in principle to having a language construct that looks like a constant and makes you think it's a constant but is actually a method call that does who knows what. There's really two different use cases here, I think, that we're conflating. ("We" meaning I think we're all doing it to an extent.) 1) I want an approximately global value that is auto-memoized on first usage, so I can access it from anywhere without having to recompute it or do the work of memoizing it myself. 2) I have a code base with lots of constants, and I've changed my mind about the API (for whatever reason) and want them to no longer be constant but runtime defined. For point 1, I'd love it if we had some way to auto-memoize a result. That would be sweet. There's a couple of ways we could go about it... but I firmly believe that sticking it behind a const-like API is the wrong way to do it for the reasons above. (I wouldn't want to limit it to global-ish things, either, because global-ish things are, as stated, bad in every way and should be avoided whenever possible. Yes, I know there's a lot of bad code out there already with it; that doesn't mean encouraging it.) For point 2... if you want to change your API, then your API is going to change. That's what it means to change an API. It's no different than deciding to rename a method or class. It may or may not be hard depending on the API and the install base, but that it's a constant doesn't change matters. Making code easier to refactor is all well and good, but not if it violates all expectations around what a constant is. For derive-once global constants, you may be looking for `define`. That's a runtime operation and effectively boils down to a set-once global. It doesn't help with constants defined in a class, but for an already-global constant `define` already gives you a one-time set operation, just not on-demand. That's probably the better avenue to pursue for option 2, though again it's not one that I find worth compromising the language design for. --Larry Garfield -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php