On 04/05/2025 08:34, Michael Morris wrote:
PHP has no way of dealing with userland code trying to write to the same entry on the symbol tables.  Namespaces are a workaround of this and combined with autoloaders they've yielded the package environments we currently have (usually composer), but at the end of the day if two code blocks want different versions of the same package invoked at the same time there's going to be a crash. This is seen most visibly in WordPress plugins that use composer, as they resort to
monkey-typing the composer packages they consume to avoid such collisions.


I think there are two different problems being muddled here:

1) How can two *completely unrelated* libraries avoid *accidentally* declaring something with the same name? 2) How can two versions of *the same* library be used in different parts of the same running program, despite overlapping names?

Namespaces are not a workaround to problem number 2, they are a solution to problem number 1: every library chooses a prefix, and avoids declaring symbols with prefixes used by other libraries.

Problem number 2 is what you seem to be trying to address.


In languages like EcmaScript/JavaScript/TypeScript, the solution (to both problems) is to say that declarations don't have a canonical name. They're values that you can pass around, and their name is whatever a local scope says it is. This has major implications on both the language and its ecosystem:

- contracts between libraries need to be structural, because there is no name that all libraries agree on for an interface/protocol/whatever - package managers don't resolve the graph of dependencies to a consistent set, they install multiple copies of the same library, for use in different scopes - package authors are free to depend on mutually incompatible concrete implementations, rather than agreed or de facto standards and interfaces

NPM is notorious for creating a giant directory of tiny modules, because that's what the language design encourages.


That's not how PHP works, and it never will be. In PHP (and other languages like Java, and C#), declarations have a single fully-qualified name. If you want two different versions of the same library, you will need to find a way to make their declarations use different fully-qualified names.


Most applications do not have this problem. In fact, I would say that most applications would actively suffer from having multiple copies of the same library installed.

The main exception, as you have pointed out, is plugin architectures like WordPress, where the plugin might want to "privately" use some library without impacting the host application and other plugins. For those, userland solutions already exist - a random search turned up this one, which lists some alternatives: https://github.com/BrianHenryIE/strauss?tab=readme-ov-file#alternatives


I *do* think PHP would benefit from some native concept of "module" for other reasons, e.g. marking internal components, optimising across multiple files. I *do not* think that ES/JS/TS is a suitable model to look at, because it is starting from a fundamentally different concept of what a declaration is.

I also *do not* think that allowing multiple versions of the same library should be a core requirement of any native module support; enabling userland to achieve it efficiently would be a nice to have.


--
Rowan Tommins
[IMSoP]

Reply via email to