> On Jan 5, 2020, at 12:02 PM, Larry Garfield <la...@garfieldtech.com> wrote: > > 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.
Here is the problem with the crux of your argument. You are stating as a postulate that which you have not proven. The only reason constants are defined at compile time is that they have always been defined at compile time. There is _no_ reason — unless you can elaborate a specific tangible reason — why a constant _must_ be defined at compile time vs. first access. Doing the later does not change its essential state, i.e. it will still be "constant" and not change. You are arguing from the perspective of a status-quo basis that constants are compile because they thus far have been compile-time. But preexisting implementation is not a valid argument for why something must continue to be the way it is. Give me a conceptually valid reason why constants can only be defined a compile time and I may come to agree with you. Otherwise I assert your arguments are just biased on current implementation. > 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. Let's consider the fact that is PHP had never had the define() and instead implemented the `const` keyword from the start, and only allowed compile time values. If PHP had done that, you would be arguing from a status quo bias the same thing about making that dynamic. And it currently is dynamic which IMO invalidates your argument that constants must be defined at compile time. > 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. Can explore why you are opposed to is, and see if we can find a way to address the use-case I proposed in another way? > 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. I would rewrite this to say "I want a convenient syntax for values that tend to get hardcoded by developers that is easy to use and easy to read that is initialized on first usage so that it behaves like a constant." > (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.) I am going to argue that glob-ish things are _not necessarily_ bad in every way. They are bad when they introduce coupling and when they are mutable. Global-ish is much less bad when immutable, and when structured to make tracking down usage easy. But before you or anyone attacks me for saying this, realize that PHP is filled with globals that you happily use every day. Class names are globals. Namespaces are globals. Functions are globals. And AFAICT immutable class constants are no worse globals than class names. You can easily find where class constants are defined, and with a PHP analysis tool you can easily find every place where they are used, except for when people are using reflection or dynamic dispatch but they can do the same with classes and namespaces, so that's not an argument against class constants. > 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. No, I said that I wanted the API to _not_ change. You are the one forcing the change constraint here. I am arguing code should be evolvable so that APIs do not need to change. The more a language forces an API to change when requirements change, the more brittle and less fit-for-purpose the language is. The more a language does not allow refactoring without breaking an API the more it is a bad language, and that is much worse than some global constants IMO. > Making code easier to refactor is all well and good, but not if it violates > all expectations around what a constant is. Let's explore the second part of this. Languages change. And some times that changes expectations. To set the constraint that expectations cannot change is to force a language to be unable to improve. Some examples of expectation change: - PHP 7.4 preloading - My expectation is that the class files will be loaded on every page load, but with preloading they are not. - PHP 7.4 custom object serialization - My expectation is that the class instance will serialize as the class was defined, but this changes that. - PHP 7.3 const case-insensitive deprecation - My expectation that is constants are case insensitive, but now my expectation is no longer valid. - PHP 7.3 const string search functions with integer needle - My expectation that is I can pass an integer, but now my expectation is no longer valid. I could go on, but I think the point is the change in expectation is not an unreasonable thing to occur when a language evolves. We all have to continue learning. > 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. It many be changing PHP in a way you object to. But it does not "compromise the language design." That phrasing is a bit inflammatory. -Mike -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php