> On Jan 6, 2020, at 1:07 PM, Larry Garfield <la...@garfieldtech.com> wrote: > > Do not put words in my mouth and presume to know what I would think in some > hypothetical situation. That is rude and inappropriate.
I do not mean to nor want to start any conflict here. I know I felt some of your phrasing rude and so I was probably writing in frustration. Hopefully we can both moderate as conflict is not good for any of us. > You also repeatedly are accusing Rowan and I of "status quo bias" as though > it were a bad thing. Let me be clear: I entirely agree with Zeev that in a > language used by millions of people a "status quo bias" is a *very good > thing*. You are misunderstanding the definition of "status quo bias." Here is part of the definition: "Status quo bias is an emotional bias. The current baseline (or status quo) is taken as a reference point, and any change from that baseline is perceived as a loss. Status quo bias should be distinguished from a rational preference for the status quo ante, as when the current state of affairs is objectively superior to the available alternatives, or when imperfect information is a significant problem." When I used that phrase I was specifically referring to the emotional reaction vs. the rational reaction. I understand and agree when rational arguments are used, but lately in our political climate people seem to often to start with emotional arguments. And calling something an anti-pattern or the alternative a "best practice" is not a rational argument; both of those are loaded words. From: https://en.wikipedia.org/wiki/Status_quo_bias But if I mischaracterized your objections I apologize. > So you call something an anti-pattern, then get on my case for "appeal to > authority" for calling something an anti-pattern? Your argument style needs > work, dude. I notice you did not quote my full statement. I explicitly called out the irony of my own usage and made the distinction that I was not using the phrase to argue against someone else's proposal which is why I felt ok to use it, because I was not using it to block anyone else's needs. Again, my goal is not conflict but hopefully improving PHP. > Global data is well-recognized across the industry as dangerous, and the > larger the system the more dangerous it is. Eh, not exactly. Global data that is *mutable* is bad. Immutable global data — especially constants — are not necessarily bad, at least per the highest voted answer which means the topic is definitely debatable: https://stackoverflow.com/a/1265684/102699 And a constant that is initialized at runtime is still immutable through the life of the execution. > 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. > (And for the record, "appeal to authority" is only a logical fallacy if the > authority being appealed to is not a qualified authority on the topic at > hand. Appealing to Tiger Woods's authority on golf clubs is not a logical > fallacy because he really would have more knowledge and experience than most; > appealing to his authority on baseball gloves would be a logical fallacy.) When you said it was an anti-pattern you used passive voice and did not include a reference to any authority. That said, I have been programming professionally for 30 years now and I have seen many best practices from "authorities" be promoted, and then later seen a tidal wave of developer sentiment argue against those same best practices, i.e. inheritance and then containment, as one example. I've also seen authorities promote an idea and then watched as developers latched onto it and give it a life of its own, far outpacing what the authority orginally intended, e.g. Bob Martin and the single responsibility principle. In my experience "best practice" and "anti-patterns" are too often used in debate even when they do not actually apply to the use-case, so I prefer to dispense with those words when trying to debate actual pros and cons of an approach. > 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. > 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. That is exactly what I am trying to change. > It makes any sort of dynamic override (which you *must* do in a cloud hosting > environment) a PITA. Exactly. > The best option are systems that are configured by env vars, and have a very > clearly set of documented env vars to populate. Env vars are also globally > readable but you're not tricked into thinking they're compiled out at > compilation time (as things with `const` are.) They're also by far the > easiest for me to work with as the person writing that glue code. The word "tricked" is a pejorative and not helpful for our discussion. What I read here is that you have a preference for using Env vars directly and I have a preference for encapsulating them into constants. I don't see that either of us are more "right" than the other, we just have different preferences. I still have not heard a real reason why Api::URL is somehow worse to use than $config->api_url() other than your claim that the former is "global" and thus bad, which I challenge because the former would be immutable. This is one of the areas where I think the "anti-pattern" does not apply. > Adding language features that make it easier for people to take the approach > that is in my experience the most painful option is something I am not going > to support. :-) Have you worked with other languages besides PHP where dynamically initialized constants were possible, and this caused problems? > To the use cases, "I'm changing the API but don't want to change the API" > (what you're calling evolving here) As you said above that it was rude to put words in your mouth, it is also rude to keep changing my words to better fit your argument. Let us both not do that. > "Sometimes a constant is not a constant". What I proposed will always be a constant. Again, it would be immutable once set. The fact is it set at compile time does not make it constant, per the lin > From one perspective one could look at dynamically valued constants as a zero > parameter self-memoizing function with some syntactic sugar. Yes. Although I tend to avoid using the term "memoizing" because most people I know have to look it up and then ponder over its meaning. > 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? Those would definitely be very useful, but unfortunately would not address the use-case I presented. > 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? 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. If a dynamic constant were to use $_GET or $_ENV it could be problematic, but it could also be coding in a manner than it would be completely robust, and making it robust is not hard. > (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. > So I could get behind dynamically valued constants and/or auto-memoizing > functions. That would probably mean they still have a $ on them, which > doesn't bother me. That clearly separates them visually from macro > constants, which I like. Having the $ requirement blocks my primary use-case, so it would bother me. > The potential for hard to find bugs here is high; although the counter point > is that using a function/method to emulate them today, which you can > absolutely do, offers the exact same risk. And that's the key point. It really is no different from what we have today, except that what I proposed would provide evolvability. > 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? Are you concerned that the code could fail and leave the constant in an invalid state? A potential way to address that is for a dynamic constant to require type hinting, and thus if it did not return the correct type it would fail with an easy to trace error output. And also disallow throwing errors outside of the constant. That would force developers to write robust dynamic constant code. -Mike