Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:124018 X-Original-To: internals@lists.php.net Delivered-To: internals@lists.php.net Received: from php-smtp4.php.net (php-smtp4.php.net [45.112.84.5]) by qa.php.net (Postfix) with ESMTPS id 05CF21A009C for ; Sat, 29 Jun 2024 09:39:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1719654044; bh=pota3nnjorJdzdlRyJOQpYmKxN0loqKutJuGDraHPmM=; h=From:Subject:Date:In-Reply-To:Cc:To:References:From; b=U9eHvZt3NEYcf1GtS9b5ET8UMn/hROvZd3yoNhsiXCkK6y6rzc+qqC6PIDzkLISY6 rMmp/pa0/kpWIEfJRD/g5E8FF+5NqnNNOhxnhPebqXP6kixeMPDym3CYslqzSNsvrp IgQa5VMRIPkNsSFoRuiV7KQCfIp0uMrqITbU5RKlRNwwzx7/0BH3WlYAlFaLzvHy+s Xafn/xOX1Bp7lsCrwlR1mT1haaeJIKwqiJRqk0iC3wDoKHFsCjsY1CzPULu0bShKXL WOAvO78vGiA9Q7BLfQBPpiSFvw5sFDnKwgrCodYwUgMvosTkPOYNd7seNwVJjH36ta vcFZSicA4OmCg== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 78CB8180641 for ; Sat, 29 Jun 2024 09:40:43 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.0 (2022-12-13) on php-smtp4.php.net X-Spam-Level: * X-Spam-Status: No, score=2.0 required=5.0 tests=BAYES_50,DKIM_SIGNED, DKIM_VALID,DMARC_MISSING,HTML_MESSAGE,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_NONE,THIS_AD,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=4.0.0 X-Spam-Virus: Error (Cannot connect to unix socket '/var/run/clamav/clamd.ctl': connect: Connection refused) X-Envelope-From: Received: from mail-yw1-f171.google.com (mail-yw1-f171.google.com [209.85.128.171]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Sat, 29 Jun 2024 09:40:43 +0000 (UTC) Received: by mail-yw1-f171.google.com with SMTP id 00721157ae682-645808a3294so12692267b3.3 for ; Sat, 29 Jun 2024 02:39:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=newclarity-net.20230601.gappssmtp.com; s=20230601; t=1719653963; x=1720258763; darn=lists.php.net; h=references:to:cc:in-reply-to:date:subject:mime-version:message-id :from:from:to:cc:subject:date:message-id:reply-to; bh=GwiHq7gQ+mtpQ1j+q7Jc0NrGx+5n6L6eH4ULfKKCZpA=; b=EXgPhOnxOHJvGKGUIxaiTNddZn3xeyDHlPtoFV4UXN6Nsiwd4atGjbVh24E49LvG+I Uh1rMsKQn+AJ/gDPhzmTv6VHjRrSm6Qjl5Vq01y9UNZ/T1O/vwfe+h3afFXGVvGPZcMs g+R5bW8c0c3n1Z9XHSd/qb54g0BuCeOgzjdyUTDpERlsW51JqzcdWB6JN4j8CoPAqPny COr4wTHLyxQB/Jystdgsvt8bAxK4EJZRGELhWl9Pg3BNFNnEGmnMrYgVME+Qg+4V/M+J WfZ+Z7VzVpeqR7pJJv40oAQjSsPrUW916cBvWDNMpx05qCD1GgTcqdMf0KZ+08W75NbE /Clw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1719653963; x=1720258763; h=references:to:cc:in-reply-to:date:subject:mime-version:message-id :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=GwiHq7gQ+mtpQ1j+q7Jc0NrGx+5n6L6eH4ULfKKCZpA=; b=lF1GVpCZWNPX/j8cWwyXrndii+Z7ZYwIfBbPxvvbH5ih2SMHNNmCdnjJULBbVXpdcE 6L8CuS0QYU/oXvOYsXUOoa4+V0vhKdacgIFRjZXAxcOi/xWy6p2RLO7obslaFDV1Vl/k DrPirgiqpImFmd9me4qpzRApgdaexaMwl0k4E9WqKuvtk+GKHd2qqOp3vemZVZYKFMkQ SyAIxate3tCzQf6VQ21EviBCzCXK+XlccQ6Ewab2pxSxddW8172iNzriYGwVDgrip3tt gMtD2ZVhdCing5ou+AdXHS+A9nZL6b9RzonaEgQBx6f3DTJMpj3aACBAOWVVW7DlgVEY tFIw== X-Gm-Message-State: AOJu0YxEORl5qcgttu/qCCS4plIugExOLjbdzQGwkt79Q7y6NUTBY29G tbsv+wSWane8XgjmZqUz0ZIbgn3+/3WxWDxAWBjvMU7rpPRIRVGv7TN0Mm0Qx7y/z2HdmmByFtm Pfx0= X-Google-Smtp-Source: AGHT+IGrSJLWaJLT6YVe6zhzMeo2fWKlfkl9GgFqCbOgvw/zIDbbhZO5zzKmjU53FNa10J5u9ovAFg== X-Received: by 2002:a81:9215:0:b0:618:2f6d:ca80 with SMTP id 00721157ae682-64c71802f91mr6097947b3.12.1719653962652; Sat, 29 Jun 2024 02:39:22 -0700 (PDT) Received: from smtpclient.apple (c-98-252-216-111.hsd1.ga.comcast.net. [98.252.216.111]) by smtp.gmail.com with ESMTPSA id 00721157ae682-64a9c310859sm6235077b3.127.2024.06.29.02.39.22 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sat, 29 Jun 2024 02:39:22 -0700 (PDT) Message-ID: <72B1374D-8181-40B8-AB7A-988AFBFE5DF1@newclarity.net> Content-Type: multipart/alternative; boundary="Apple-Mail=_34903959-6D5A-4F86-B5AF-BBB882696D8D" Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net Mime-Version: 1.0 (Mac OS X Mail 16.0 \(3696.120.41.1.8\)) Subject: Re: [PHP-DEV] [Initial Feedback] PHP User Modules - An Adaptation of ES6 from JavaScript Date: Sat, 29 Jun 2024 05:39:21 -0400 In-Reply-To: <551cd5b0-1c00-4818-a9ca-97f6b7e8c3dc@app.fastmail.com> Cc: internals@lists.php.net To: "Rowan Tommins [IMSoP]" References: <1917CF7C-26D8-4DBE-B05C-5AA650AC6C9F@rwec.co.uk> <551cd5b0-1c00-4818-a9ca-97f6b7e8c3dc@app.fastmail.com> X-Mailer: Apple Mail (2.3696.120.41.1.8) From: mike@newclarity.net (Mike Schinkel) --Apple-Mail=_34903959-6D5A-4F86-B5AF-BBB882696D8D Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 > On Jun 28, 2024, at 10:12 AM, Rowan Tommins [IMSoP] = > wrote: > Namespaces don't require autoloading, and autoloading doesn't require = one file per class. No they do not, but the design of each was heavily intertwined with each = other resulting in a less than optimal design, IMO. So, are you arguing to keep one and eject the other for modules, and if = so which are you arguing we eject? Autoloading? Or are you arguing to keep both for modules, in which case your argument = above is moot? > To compile a program with multiple source files, in any language, you = need one of two things: >=20 > 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. Recursion is only needed if modules are hierarchical in nature.=20 > b) A way for the compiler to tell, based on some symbol it wants to = resolve, which file should be compiled. That presumes the compiler did not simply generate an AST from the list = of files. > 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. And that "whatever you want" takes execution time (and tracing through = when you are debugging.) But when you look at many other languages = loading is an implementation detail that PHP chose to hoist onto = userland developers when PHP could have established the rules to handle = it more performantly without userland involvement. Or is there some aspect of autoloading that could not be handled by PHP = itself? Note I am asking only within the propose scope of modules, which = we could constrain to optimize their runtime use. > 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.=20 Now you are getting somewhere. =20 Imagine that each module =E2=80=94 which could equal a single directory = =E2=80=94 could have a pre-compiled op-cache which is essentially what I = proposed in other recent emails. > 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. meh.=20 That sounds like a way to avoid discussing the ways in which smartly = designed modules could really improve PHP. >>> 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.=20 >> I can't see how package-privates would be of any value to you = *unless* you rewrite your codebase.=20 > 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". Not simple, although I admit I am being pedantic about words used here, = but for a reason. I asked about "package-privates," you responded with = "namespace-privates."=20 Adding private to namespaces is orthogonal to the discussion of = packages.=20 To require that packages be constrained to have all the same warts as = namespaces and existing PHP code simply so you can have = namespace-privates is short-sighted (and IMO a bit selfish.)=20 Alternately, namespaces could get private scope in parallel to having = modules be considered.=20 That would allow modules to gain improvements that we could not get by = having to maintain BC with namespaces. Which causes me to ask: If you have really wanted namespace private why = has it been six years since it was even last mentioned on the list, and = four years since last discussed? =20 https://externals.io/message/101323 = Why has there not been an RFC since this one = https://wiki.php.net/rfc/namespace-visibility = six years ago, that was = not even voted on? Why is it that when the topic of addressing modules/packages comes up = =E2=80=94 which has been talked about numerous times in the past six = years =E2=80=94 do you now bring up namespace privates in a manner that = would effectively torpedo goals of the modules discussion, at least from = the perspective of the OP and myself? =20 If namespace private were really something important to you, why haven't = you championed it before, rather than hijack a discussion about the = benefits we could get from modules if not constrained by namespaces? > 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". Then don't. Champion this RFC = https://wiki.php.net/rfc/namespace-visibility = and get what you want.=20= But please don't argue against a discussion on modules because you want = a feature that can be gotten orthogonally. (If you must argue against = it, make arguments for which accommodations for your preferences cannot = be found.) > 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. And that is bad, how? But before you answer, it just means that instead of a `use` statement = in your existing code you change to a `import` statement.=20 You'd then of course need to changes =E2=80=94 if applicable =E2=80=94 = to call the new Symphony Mailer, but you'd have to do that with or = without modules. Or is there something else I am missing? >> As for package-level optimisation, you'll need to give examples of = what you mean there as I don't want to wrongly assume. >=20 > Currently, OpCache only optimises per file, because it can't guarantee = how files will be used together. >=20 > 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. Thank you for elaborating on that.=20 So, champion an RFC to improve OpCache for namespaces. That need not = impose on the discussion about modules. Further, and this is what is nice about being able to discuss modules = not having to be compatible with namespaces, if there are aspect of = namespaces that make optimization hard or impossible then we could = potentially set up rules of modules that make similar optimizations easy = and/or possible. EVEN further, consider the fact that in PHP all class members are public = by default. One thing we could have in modules is to go back to short = `var` and eliminate both `private` and `protected` modifiers and only = have `public` with the default behavior being what is `private` outside = of modules. `protected` would no longer be needed as we would have = module scope which is defacto-`protected`. Classes could be `final` by default in modules and then we could modify = them with an `open` keyword (thanks to Lynn for that one.) And so on. In other words, if we could treat modules as their own = sandbox, we could get fix many of the regrettable former design choices = of the PHP language =E2=80=94 some of which are to make PHP be beginner = friendly =E2=80=94 and potentially re-energize people who once looked at = PHP and dismissed it to give it another look. > 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. Why can we not just treat namespaces and modules as completely = separate things? > 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. That feels like a frivolous concern when compared to the benefits we = could see with modules, especially when there would be ways to mitigate = your stated concerns here. If you don't like to see imports, but your imports in a namespace and = then "use" that namespace. Or we could allow "use module" instead of (or in addition to) "import" = and then it could look more pleasant for you. As for conflicting semantics: 1.) I'm not seeing how those could be significant in the using/importing = file, and=20 2.) Isn't dealing with conflicting semantics just a part of programming? = =20 3.) Don't "use" and "use function" have conflicting semantics? =20 God knows that "use" by itself has many confusing semantics, which = "import" could avoid. > 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. "use module" would work just as well as "import"; the "import" is not = special, the module scoping and features are what is valuable here. For specifics see my other recent emails on the subject. If they do not = explain, please ask again with specifics. > 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. And that is what I am trying to get away from.=20 First the backslash =E2=80=94 because when using in reflection or other = dynamic programming they have to be escaped which can lead to escaping = errors. I know you don't care, but I and others do. Second, the hierarchy. Because there is no constraint on hierarchy PHP = subtly encourages developers =E2=80=94 as if sirens of the Odyssey =E2=80=94= to create large hierarchies. I even find myself doing it as I fighting = myself against it. =20 The reasons hierarchy is bad is: 1.) larger hierarchies grow conceptual complexity,=20 2.) they place no limit on package growth as you can always create = subdirectories, 3.) they make it harder to "see" all the code files in one place (a = single directory), 4.) they constrain where code is located when there are benefits to a = different layout > 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. Revisiting this, why is it important to you that "new \Foo\Bar\Baz" = refer to a "packaged" class vs a namespaced class, assuming you had = namespace-private and OpCache improvements? Why can't you still just use the namespaces you prefer and let = "packages" (modules) improve in other ways? I am trying my best not to make this ad-hominem so forgive me but I do = have to ask if this is just not a case of "I am comfortable doing it the = way I have been doing it and do not want to consider changing," maybe? = Note I am asking that question limited to the one statement I quoted = above, not on the broader discussion. >> 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. >=20 > Again, this is entirely about code style, and not something the = language can control. A language cannot control it, but a language can encourage or discourse = it.=20 And the PHP language encourages a large amount of file and directory = bloat. =20 One only need to compare the number of files in most PHP libraries to = the number of files in JS or Go package to see that the nature of a = language clearly does not influence. To bring stats vs. opinion I asked ChatGPT what the two equivalent = packages are to Symphony for JS and Go respectively and it suggested = ExpressJS and Gin. So I cloned them to see the number of files and = directories each has. =46rom the root of each repo: Project Files Dirs Symfony: 12,504 2,162 ExpressJS: 259 87 Gin(GoLang): 145 30 The comparison might not be completely fair given how much longer = Symfony has been around, but they all target the same use-case so even = if there is less functionality in ExpressJS or Gin.=20 Given that I think that well over an order of magnitude more files is a = really odiferous code smell, and is thanks to the language which = admittedly cannot "control" layout, but definitely influences it. Am I wrong? Present any other relatively equivalent project comparisons = you please. Here are the bash commands to count files and dirs: find /path/to/subdirectory -type f | wc -l find /path/to/subdirectory -type d | wc -l > 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. I can't speak for the OP, but nothing I am proposing is advocating for = separate packages for every tiny functions. Nothing. Instead I am advocating for packages that are mostly in a few = directories instead of almost two magnitudes more! >> 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. >=20 > If and when an actual problem arises, let's discuss it. Not "problems" but instead "opportunities." I have already pointed out numerous opportunities in this email and one = of my recent emails. >>> 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=20 >>> 400_000 packages available on Packagist, and billions of lines of = existing code? >>=20 >> 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. >=20 > No, I'm saying that every one of those packages could benefit if we = make incremental changes. Maybe.=20 What benefits can you envision you would get if PHP made = namespaces=3D=3Dmodules compared with the benefits I have mentioned for = making modules not be constrained to compatibility with namespaces = (besides private and OpCache as we already discussed you pursue for = namespaces?) Can we get precompiling for modules in a directory and written to a = `.php.module` file? We can't do that with namespaces because scanning = recursively could take too long at runtime. Can we get default private for all symbols and class members in = namespaces? No, that would be a huge BC break. Can we get namespaces to be first-class AST participants? If yes, why = have we not done it before? I could go on, but this email is getting loooong. > 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. And I am not advocating that. I am advocating you should get "namespace = private." Hey RFC is already written! = https://wiki.php.net/rfc/namespace-visibility = And most of the other benefits of modules as I am proposing would be BC = breaks so you could not get them in namespaces anyway. =20 Unless you can come up with something besides private and opCache I had = not considered. > 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. I am not aware of any discussion of opting in, flags, nor auditing with = respect to modules. -Mike= --Apple-Mail=_34903959-6D5A-4F86-B5AF-BBB882696D8D Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset=utf-8
On Jun 28, 2024, at 10:12 AM, Rowan Tommins [IMSoP] <imsop.php@rwec.co.uk> wrote:
Namespaces don't require autoloading, and autoloading doesn't = require one file per class.

No they do not, but the design of each was heavily = intertwined with each other resulting in a less than optimal design, = IMO.

So, are = you arguing to keep one and eject the other for modules, and if so which are you arguing we = eject? Autoloading?

Or are you arguing to keep both for modulesin which case = your argument above is moot?

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.

Recursion is only needed if modules are hierarchical in = nature. 

b) A way = for the compiler to tell, based on some symbol it wants to resolve, = which file should be compiled.

That presumes = the compiler did not simply generate an AST from the list of = files.

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.

And that "whatever you want" takes execution time (and tracing through when you are debugging.) But = when you look at many other languages loading is an implementation = detail that PHP chose to hoist onto userland developers when PHP could = have established the rules to handle it more performantly without = userland involvement.

Or is there some aspect of autoloading that could not be = handled by PHP itself? Note I am asking only within the propose scope of = modules, which we could constrain to optimize their runtime = use.

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. 

Now you are getting somewhere.  

Imagine that each module =E2=80=94 = which could equal a single directory =E2=80=94 could have a pre-compiled = op-cache which is essentially what I proposed in other recent = emails.

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.

meh. 

That sounds like a way to avoid discussing the ways in which = smartly designed modules could really improve PHP.

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

Not simple, = although I admit I am being pedantic about words used here, but for a = reason.

I = asked about "package-privates," you responded with = "namespace-privates." 

Adding private to namespaces is orthogonal to the discussion = of packages. 

To require that packages be constrained to have all the same = warts as namespaces and existing PHP code simply so you can have = namespace-privates is short-sighted (and IMO a bit = selfish.) 

Alternately, namespaces could get private scope in parallel = to having modules be considered. 

That would allow modules to gain = improvements that we could not get by having to maintain BC with = namespaces.

Which causes me to ask: If you have really wanted namespace = private why has it been six years since it was even last mentioned on = the list, and four years since last discussed?  


Why has there not been = an RFC since this one https://wiki.php.net/rfc/namespace-visibility six = years ago, that was not even voted on?

Why is it that when the topic of = addressing modules/packages comes up =E2=80=94 which has been talked = about numerous times in the past six years =E2=80=94 do you now bring up namespace privates in = a manner that would effectively torpedo goals of the modules discussion, = at least from the perspective of the OP and myself?  

If namespace private = were really something important to you, why haven't you championed it = before, rather than hijack a discussion about the benefits we could get = from modules if not constrained by namespaces?


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

Then don't. Champion this RFC https://wiki.php.net/rfc/namespace-visibility and = get what you want. 

But please don't argue against a discussion on modules = because you want a feature that can be gotten orthogonally. (If you must = argue against it, make arguments for which accommodations for your = preferences cannot be found.)

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.

And that is bad, = how?

But = before you answer, it just means that instead of a `use` statement in = your existing code you change to a `import` statement. 

You'd then of course = need to changes =E2=80=94 if applicable =E2=80=94 to call the new = Symphony Mailer, but you'd have to do that with or without = modules.

Or is = there something else I am missing?

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.

Thank you for = elaborating on that. 

So, champion an RFC to improve OpCache for namespaces. That = need not impose on the discussion about modules.

Further, and this is what is nice about = being able to discuss modules not having to be compatible with = namespaces, if there are aspect of namespaces that make optimization = hard or impossible then we could potentially set up rules of modules = that make similar optimizations easy and/or possible.

EVEN further, consider = the fact that in PHP all class members are public by default. One thing = we could have in modules is to go back to short `var` and eliminate both = `private` and `protected` modifiers and only have `public` with the = default behavior being what is `private` outside of modules. `protected` = would no longer be needed as we would have module scope which is = defacto-`protected`.

Classes could be `final` by default in modules and then we = could modify them with an `open` keyword (thanks to Lynn for that = one.)

And so = on. In other words, if we could treat modules as their own sandbox, we = could get fix many of the regrettable former design choices of the PHP = language =E2=80=94 some of which are to make PHP be beginner friendly = =E2=80=94 and potentially re-energize people who once looked at PHP and = dismissed it to give it another look.

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.

Why can we not just treat namespaces and modules as = completely separate things?

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.

That feels like a = frivolous concern when compared to the benefits we could see with = modules, especially when there would be ways to mitigate your stated = concerns here.

If you don't like to see imports, but your imports in a = namespace and then "use" that namespace.

Or we could allow "use module" instead = of (or in addition to) "import" and then it = could look more pleasant for you.

As for conflicting semantics:

1.) I'm not seeing how those could be significant = in the using/importing file, and 
2.) = Isn't dealing with conflicting semantics just a part of programming? =  
3.) Don't "use" and "use function" = have conflicting semantics?  

God knows = that "use" by itself has many confusing semantics, which "import" could = avoid.

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.

"use module" would work just as well as = "import"; the "import" is not special, the module scoping and features = are what is valuable here.

For = specifics see my other recent emails on the subject. If they do not = explain, please ask again with specifics.

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.

And that is what = I am trying to get away from. 

First the backslash =E2=80=94 because = when using in reflection or other dynamic programming they have to be = escaped which can lead to escaping errors.  I know you don't care, = but I and others do.

Second, the hierarchy. Because there is no constraint on = hierarchy PHP subtly encourages developers =E2=80=94 as if sirens of the = Odyssey =E2=80=94 to create large hierarchies. I even find myself doing = it as I fighting myself against it.  

The reasons hierarchy is bad = is:

1.) larger = hierarchies grow conceptual complexity, 
2.) = they place no limit on package growth as you can always create = subdirectories,
3.) they make it harder to "see" = all the code files in one place (a single directory),
4.) they constrain where code is located when there are = benefits to a different layout

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.

Revisiting this, why = is it important to you that "new \Foo\Bar\Baz" refer to a "packaged" = class vs a namespaced class, assuming you had namespace-private and = OpCache improvements?

Why can't you still just use the namespaces you prefer and = let "packages" (modules) improve in other ways?

I am trying my best not to make this = ad-hominem so forgive me but I do have to ask if this is just not a case = of "I am comfortable doing it the way I have been = doing it and do not want to consider changing," maybe? =  Note I am asking that question limited to the one statement I = quoted above, not on the broader discussion.

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.

A language = cannot control it, but a = language can encourage or discourse it. 

And the PHP language encourages a large amount of file and directory = bloat.  

One only need to compare the number of files in most PHP = libraries to the number of files in JS or Go package to see that = the nature of a language clearly does not influence.

To bring stats vs. opinion I asked ChatGPT what the two = equivalent packages are to Symphony for JS and Go respectively and it = suggested ExpressJS and Gin.  So I cloned them to see the number of = files and directories each has. =46rom the root of each repo:

= Project Files  = Dirs
Symfony:  12,504  2,162
ExpressJS:  259       = 87
Gin(GoLang):  = 145      = 30

The comparison might not be completely = fair given how much longer Symfony has been around, but they all target = the same use-case so even if there is less functionality in ExpressJS or = Gin. 

Given= that I think that well over an order of magnitude more files is a = really odiferous code smell, and is thanks to the language which = admittedly cannot "control" layout, but = definitely influences it.

Am I wrong?  Present any other relatively equivalent = project comparisons you please. Here are the bash commands to count = files and dirs:

find /path/to/subdirectory -type f | wc -l
find = /path/to/subdirectory -type d = | wc -l
<= blockquote class=3D"" style=3D"margin: 0px 0px 0px 40px; border: none; = padding: 0px;">
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.

I can't speak for the OP, but nothing I = am proposing is advocating for separate packages for every tiny = functions. Nothing.

Instead I am advocating for packages that are mostly in a few = directories instead of almost two magnitudes more!

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.

Not "problems" but instead "opportunities."

I have already pointed = out numerous opportunities in this email and one of my recent = emails.

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.

Maybe. 

What benefits can you envision you would get if PHP made = namespaces=3D=3Dmodules compared with the benefits I have mentioned for = making modules not be constrained to compatibility with namespaces = (besides private and OpCache as we already discussed you pursue for = namespaces?)

Can= we get precompiling for modules in a directory and written to a = `.php.module` file?  We can't do that with namespaces because = scanning recursively could take too long at runtime.

Can we get default = private for all symbols and class members in namespaces? No, that would = be a huge BC break.

Can we get namespaces to be first-class AST participants? If = yes, why have we not done it before?

I could go on, but this email is = getting loooong.

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.

And I am not = advocating that. I am advocating you should get "namespace private." Hey = RFC is already written!  https://wiki.php.net/rfc/namespace-visibility

And most of the other = benefits of modules as I am proposing would be BC breaks so you could = not get them in namespaces anyway.  

Unless you can come up with something = besides private and opCache I had not considered.

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.

I am not aware of any discussion = of opting in, flags, nor auditing with respect to = modules.

-Mike= --Apple-Mail=_34903959-6D5A-4F86-B5AF-BBB882696D8D--