On Fri, 28 Jun 2024, at 09:12, Mike Schinkel wrote:
> 
>> On Jun 28, 2024 at 2:54 AM, <Rowan Tommins [IMSoP]> wrote:
>> I don't see any particular relationship between namespaces and autoloading, 
>> or any reason we need to throw them away to introduce different conventions 
>> for loading files. 
>> 
> 
> 
> Sure, you can make the argument they are not related, but then you have to 
> ask if namespaces would look the way they do if it were not for the need to 
> map them to be able to autoload symbols.  I do not think they would.
> 
> Autoloading is by-nature one symbol per file. Namespaces were designed for 
> mapping with "<namespace>/<className>.php" to allow autoloading.
> 
> Having worked in languages that do not require having to think about or run 
> userland code to handle autoloading nor have to be concerned about loading in 
> the proper order has been such a joy when compared to the pain of working PHP.

Namespaces don't require autoloading, and autoloading doesn't require one file 
per class.

To compile a program with multiple source files, in any language, you need one 
of two things:

a) A list of files you want to compile. Maybe auto-generated, maybe done with a 
recursive iteration over a directory, but ultimately the compiler needs a file 
path to process.
b) A way for the compiler to tell, based on some symbol it wants to resolve, 
which file should be compiled.

PHP originally provided only option (a), via the include and require keywords. 
Autoloading adds option (b), where you provide a function which takes a class 
name and does *whatever you want* to find the definition.

I think it might be time to re-visit the tooling around option (a), as OpCache 
makes the cost of eagerly loading a list of files much lower than it was when 
autoloading was added. That could be as simple as include_all($directory), or 
as fancy as include_from_manifest_file($some_crazy_binary_file_format); either 
could be implemented right now in userland, because it all eventually comes 
down to calling include or require.


>> My opinions match Larry's almost exactly: I want package-level optimisation, 
>> and package-private declarations. But I don't want to rewrite my entire 
>> codebase to start using a completely different naming system. 
> 
> 
> I can't see how package-privates would be of any value to you *unless* you 
> rewrite your codebase. 


Simple: I have private Composer packages, right now, that group all their 
classes under a particular namespace prefix. I want to be able to mark some 
classes in that namespace as "internal".

I do not want to change every place that uses the existing classes to reference 
"ModuleName@ClassName" instead of "NamespacePrefix\ClassName", or change every 
"use" to "import from".


> 
> And rewrite your entire codebase? Why? No need to rewrite if you don't need 
> the specific features.  Just because there is a new feature doesn't mean you 
> have to use it if there is no benefit to you using it.


Code doesn't existing in isolation; if Symfony Mailer is re-published as a 
"module", every single application that uses it needs to change their code from 
referencing namespaced classes, to having "import" statements.


> 
> As for package-level optimisation, you'll need to give examples of what you 
> mean there as I don't want to wrongly assume.

Currently, OpCache only optimises per file, because it can't guarantee how 
files will be used together.

A simple example is function fallback: if you could declare a package as 
"completely loaded", OpCache could replace all references to "strlen" with 
"\strlen", knowing that no namespaced function with that name could be added 
later.



> 
>> Not to mention that working with a combination of existing namespaced 
>> packages and "new shiny module" packages is going to be inevitable, so we 
>> can't just hand-wave that away. 
> 
> 
> I do not follow your train of thought here. 
> 
> What specifically are you accusing me of "hand-waving away?"

I didn't intend it as a personal accusation, apologies if it came across that 
way.

What I meant was: we can't just treat namespaces and modules as completely 
separate things, and assume that every code file will be using one style or the 
other. We have to imagine the user experience when there is a mix of the two.

I can't imagine it being pleasant to have a mix of "import" and "use" 
statements at the top of a file, with different and even conflicting semantics.


> 
>> >1. Adding a module/package system to PHP with modern module features
>> 
>> I find that "modern" often just means "fashionable". Please, let's be 
>> specific.  
>> What is different between imports and namespaces, and why is it a good thing?
> 
> 
> 1. Namespaces are a parsing construct but not an AST construct beyond 
> scoping. This has many ramifications which have often been mentioned as 
> limitations on this mailing list.
> 
> 2. Namespaces cannot provide code isolation and encapsulation, unlike more 
> "fashionable" modules/packages. ;-)
> 
> 3. Namespaces have no runtime behavior, but more "fashionable" 
> modules/packages often do.


Perhaps I didn't word the question well. What I'm really asking, as someone 
who's never used JS or Go modules, is why I'd want to write "import", rather 
than referencing a global name in a hierarchy.

That's really all I mean by "making it compatible with namespace": I want "new 
\Foo\Bar\Baz;" to be able to refer to a "packaged" class, probably by having a 
way to mark all classes under "\Foo\Bar" as belonging to a particular package.


> 
> 4. The usage of the escape character for namespace separator makes dynamic 
> programming tedious and error prone.

Sorry, not interested.


>> 
> 5. Because of one-to-one symbol-to-file for autoloading, Namespaces by nature 
> result in a large number of files in a large number of directories and do not 
> allow code organization optimized for cohesiveness. 

See above - this is not related to namespaces.


> 
> 6. Modules and packages are typically small-scoped to a single directory and 
> it is a code smell to have many different packages tightly coupled, as is the 
> case with namespaces. Forcing modules to munge with namespaces would mean 
> most modules would be written with those code smells for years because that 
> will be how everyone doing a quick shift from namespace to module will write 
> their modules.

Again, this is entirely about code style, and not something the language can 
control.

Also, the JS insistence on having a separate package for every tiny function is 
a common source of criticism, so personally I am very happy that PHP packages 
are generally larger than that.


> 
> 7. In designing modules, if modules and namespaces were munged together then 
> every single design decision made for modules will have to be compatible with 
> namespaces.  I cannot currently know what all constraints will emerge but I 
> can almost guarantee that modules would be less well-designed if they have to 
> be shoehorned to be fully compatible with namespaces.
> 
> That said, maybe the best solution is to NOT put the stake in the ground 
> right now and say "They must be namespace compatible" or "They must not be 
> namespace compatible" but move forward with an open mind so that we can tease 
> out exactly how namespaces would constrain modules and and then make the 
> decision later for what would be in the best interest of moving PHP into the 
> future.

If and when an actual problem arises, let's discuss it.


>> What specifically stops us doing all the things you've been discussing 
>> around loading, and visibility, etc, in a way that's compatible with the 
>> 400_000 packages available on Packagist, and billions of lines of existing 
>> code?
> 
> You speak as if I am proposing getting rid of namespaces and making those 
> 400_000 packages available on Packagist, and billions of lines of existing 
> code not work in PHP.  Of course not.

No, I'm saying that every one of those packages could benefit if we make 
incremental changes.

I don't want to couple it so that you can't have "package private" without also 
switching to some new "advanced" dialect of the language, and I don't see any 
reason why we need to do so.

Maybe package scoped declares could allow opting in to certain checks, but I 
don't think "is in a package" and "has been audited for a load of extra 
breaking changes" should be set by the same flag.


Leaving the rest of your reply here, since you accidentally sent it privately:

> 
> What I am saying is that we should design modules from a cleaner slate than 
> namespaces, and allow solving problems that concerns for BC have always 
> stopped PHP from solving.  
> 
> Besides, when a language evolves and adds new features, it rarely works to 
> shoehorn existing code AS-IS into the new constructs because doing so does 
> not take advantage of the new capabilities.  Just because you have a ton of 
> code written for namespaces doesn't mean modules should be constrained to 
> make it easy for you to move your namespaces to modules without a redesign. 
> 
> But as I am proposing your namespaced code would continue to work exactly as 
> before.
> 
> By their nature, beginners would not be as likely to use modules and would be 
> likely to stick to existing PHP style. Intermediate to advanced programmers 
> could instead be the target market for modules.  
> 
> There has always been a divide in PHP between those who want a really 
> advanced language and are happy to break compatibility to get there, and 
> those who want PHP just the way it has always been. Modules could easily 
> require typing for all things that can be typed, for example. Modules could 
> be the thing that finally addresses the needs of intermediate to advanced 
> developers while keeping everyone else who wants to keep PHP as more beginner 
> friendly language happy. 



--
Rowan Tommins
[IMSoP]

Reply via email to