Re: Module or Class Visibility, Season 2

From: Date: Sun, 01 Jun 2025 16:05:32 +0000
Subject: Re: Module or Class Visibility, Season 2
References: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20  Groups: php.internals 
Request: Send a blank email to [email protected] to get a copy of this message
On Sun, Jun 1, 2025, at 12:26 AM, Michael Morris wrote:


> $myModule = require_module('file/path');
>
> or perhaps
>
> const myModule = require_module('file/path');
>
> The module probably should return a static class or class instance, but 
> it could return a closure.  In JavaScript the dynamic import() 
> statement returns a module object that is most similar to PHP's static 
> classes, with each export being a member or method of the module object.
>
> Circling back to a question I know will be asked - what about 
> autoloaders?  To which I answer, what about them? If the module wants 
> to use an autoloader it has to require one just as the initial php file 
> that required it had to have done at some point.  The container module 
> is for all intents and purposes its own php process that returns some 
> interface to allow it to talk to the process that spawned it. 
>
> Will this work? I think yes. Will it be efficient? Hell no. Can it be 
> optimized somehow? I don't know.

I think there's a key assumption here still that is at the root of much of the disagreement in
this thread.

Given that code from multiple files is clustered together into a "thing"
and Given we can use that "thing" to define a boundary for:
* name resolution (what Michael is after);
* visibility (what I am after);
* more efficient optimizations (what Arnaud showed is possible);
* various other things
Then the key question is: Who defines that boundary?

Is it the code *author* that defines that boundary?  Or is it the code *consumer*?  

Similarly, is it the code author or consumer that has to Do Work(tm) in order to leverage the
desired capability?  Or both?

This is an abstract question that I think needs to be resolved before we go any further.  There are
certainly ways to do it with either party in control of the boundary, but I suspect many of them
will be mutually-exclusive, so deciding which tradeoffs we want and what future features we're
OK with blocking is highly important.

My own take:

The boundary *must* be definable by the author.  The author knows the code better than the consumer.
 The odds of the author botching the boundary and making subtle bugs is orders of magnitude less
than the consumer of the code botching the boundary.  (Eg, if a class is declared module-private,
but it's the consumer that defines what module it is in, then access to that class is
completely out of the control of the author and it's really easy for some code to break.) 
Potentially we could allow the consumer to decide how they want to leverage that boundary (either by
just using the code as is normally now, or wrapping it into a name resolution container), but the
boundary itself needs to be author-defined, not consumer defined, or things will break.

I realize that makes it less useful for the goal of "support old and unmaintained WordPress
plugins that haven't been updated in 3 years" (as it will be about 15 years before WP
plugins that have bothered to make modules/containers/boundaries get abandoned), but my priority is
the consistency and reliability of the language mroeso than supporting negligent maintainers.

One possible idea: Starting from the proposal Arnaud and I made earlier (see earlier posts), have a
Module.php file rather than module.ini, which defines a class that specifies the files to
include/exclude etc.  Then in addition to the "just use as it is" usage pattern we
described, the consumer could also run something like:

$container = require_modules(['foo/Module.php', 'bar/Module.php'], containerize:
true);

Which would give back an object/class/thing through which all the code that was just loaded is
accessed, creating a separate loading space that is build along the boundaries established by the
module/package authors already.  (Note: This still relies on all of those packages being modularized
by their authors, but again, I think that is a requirement.)

--Larry Garfield


Thread (50 messages)

« previous php.internals (#127523) next »