On 8 July 2024 04:25:45 CEST, Jordan LeDoux <[email protected]> wrote:
>I think it's strange that this discussion has driven deep down the tangent
>of versioning...
[...]
>Things like separating global scope between importer and importee, managed
>visibility of symbols and exports from modules/packages, allowing for
>separate autoloaders for things which are called or included via an import,
>etc. Those are the things that the language itself can do.
>
>All this other stuff feels like a distraction.
I agree. I wrote most of the below a couple of days ago, but I don't think it posted correctly,
so apologies if some people see it twice:
Autoloading is just a way to load files later, by the engine telling you when a class is first
needed. PHP does not, and should not, make any assumptions about how files are laid out on disk; an
autoloader doesn't actually need to load any files at all, and if it does, it uses the same
include or require statements which have been in PHP for decades.
Likewise, installing packages and defining version schemes is a completely separate problem space
that can probably be served by a few small tweaks to Composer once the language provides the
underlying functionality.
The core of the problem you seem to want to solve is this: if you have two files foo_1.php and
foo_2.php, which both define a class \Acme\Foo, how do you load both of them, so that you end up
with two differently named classes?
In JS, that's easy, because functions and object constructors (and "classes") exist
as objects you can pass around as variables, they don't need to know their own name. In PHP,
everything is based on the idea that functions and classes are identified by name. You can rewrite
the name in the class declaration, and in direct references to it, but what about code using
::class, or constructing a name and using "new $name", and so on? How will tools using
static analysis or reflection handle the renaming - e.g. how does DI autowiring work if names are in
some sense dynamic?
You've also got to work out what to do with transitive dependencies - if I "import
'foo_1.php' as MyFoo", but Foo in turn has "import 'guzzle_2.php' as
MyGuzzle", what namespace do all Guzzle's classes get rewritten into? What about
dependencies that are specifically intended to bridge between packages, like PSR-7 RequestInterface?
My advice: start with the assumption that something has already installed all the files you need
into an arbitrary directory structure, and something is going to generate a bunch of statements to
load them. What happens next, in the language itself, to make them live side by side without
breaking? If we get a solid solution to that (which I'm skeptical of), we can discuss how
Composer, or the WordPress plugin installer, would generate whatever include/import/alias/rewrite
statements we end up creating.
Regards,
--
Rowan Tommins
[IMSoP]
Rowan Tommins
[IMSoP]