On Mon, Jan 6, 2020, at 2:28 PM, Mike Schinkel wrote:
> > On Jan 6, 2020, at 1:07 PM, Larry Garfield <la...@garfieldtech.com> wrote:

*snip*

> From: https://en.wikipedia.org/wiki/Status_quo_bias
> 
> But if I mischaracterized your objections I apologize.  

I am not anti-change for anti-change's sake.  Since I presume from earlier 
comments that you're familiar with my background in Drupal I think that is 
sufficient evidence that I am not against change as a concept. :-)

Let us move on.

> >  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.

Yes, PHP doesn't have pure functions as an explicit thing.  This makes me sad. 
:-)  The point here is that when I call a function in PHP, I intuitively expect 
that it may not be pure, or may be context-sensitive.  That may be desireable 
or not in context, but the () indicate "code will run, and code may do weird 
stuff".  When I see a constant, I expect it to be, well, constant, 
deterministic, and have a small fixed performance impact.  (In the case of 
`const`, zero performance impact.)

For example:

const DEBUG_MODE = false;

function foo() {
  if (DEBUG_MODE) {
    // Do stuff.
  }
}

PHP will currently (AIUI) inline the DEBUG_MODE value at compile time, notice 
that the code path is unreachable, and omit it from the compiled opcodes 
entirely.  (I'm pretty sure it does that now, at least; if not, it certainly 
can be.)

If you use a define, however:

define(DEBUG_MODE, $_ENV['debug'] ?? false);

function foo() {
  if (DEBUG_MODE) {
    // Do stuff.
  }
}

That optimization cannot happen.  But just from looking at foo() I cannot tell 
which is going to happen.  I view that as a negative.


> > 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.

I know; I included that as a resume so that my following points would carry 
more experiential weight.  (And because we really were doing it before 
Pantheon, who is a competitor of ours, so there. :-) )

> > 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. 

No, it's because you cannot override them.  It makes the conditional logic 
around defining them more complicated.  Specifically, with WordPress for 
example, I cannot just leave WP's default config script in place and tack ours 
on before/after it.  I have to hack theirs up and replace it with one that 
checks every possible source for DB configuration information and then set it 
once, because it cannot then be overridden.  They actually *are* set 
dynamically with declare().  The runtime dynamism isn't the issue.  In this 
case it's actually the immutability that causes the problem, ironically enough. 
:-P

An example of where I can see problems: In some systems, $_GET is treated as 
mutable.  It is, but modifying it is generally a bad idea, but people do it 
anyway.  For instance, I've seen "clean URLs" implemented by modifying the 
$_GET variable and $_SERVER variable to mutate example.com/foo/bar into 
example.com/index.php?q=foo/bar.  (Drupal 7 for instance did that.)

Now suppose you have a lazy-loading "constant" that uses $_GET.  If it gets 
called before that conversion happens in some code paths but not others, its 
value will be unpredicatable.  It may get built before $_GET['q'] is changed or 
after, which would change its value.

That's not something I ever expect a "constant" to do.  I expect a constant to 
be constant from one request to another, even if it nominally isn't derived 
until runtime.  Constants that change value are not constant.

(Is this a subjective and partially emotional interpretation?  Of course it is. 
 Much of language design, like any other design, is.  But I don't think my 
subjective view here is unique.)


> > 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?   

Yes.  Or the static class property example with color from the Java URL you 
provided, which is a nice use case.

> Those would definitely be very useful, but unfortunately would not 
> address the use-case I presented.

The specific use case you presented is not one I believe PHP should support.  
If I have not convinced you of my position on that yet, I don't think I am 
going to, nor are you going to convince me of yours.

> > 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?

I am thinking aloud and allowing the available options to go where they 
logically go.

> 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.  

Certainly.  But a good language nudges people toward writing good code, or at 
least not-bad code.  (How hard it should nudge is a subject of much debate and 
is one of the reasons we have many languages.)

> >  (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.

See the $_GET['q'] example above for the sort of unpredictability I am 
concerned about.  In a long-running process the potential for such issues is 
higher.

> > 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?  

Any dynamic constant variable has a lifetime of its scope.  If global, then 
it's the lifetime of the process.  

> Are you concerned that the code could fail and leave the constant in an 
> invalid state? 

That wasn't what I was thinking of, although I suppose that's also a concern.  
I was more thinking of the inconsistent initialization time, as in my earlier 
example, leading to a constant that is variable request-to-request even if it's 
nominally constant-once-set within a specific request.  That's a very different 
behavioral pattern from guaranteed consistent request-to-request.  IMO they 
should remain separate.

--Larry Garfield

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to