Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:127363 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 lists.php.net (Postfix) with ESMTPS id CF6551A00BC for ; Wed, 14 May 2025 21:28:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1747257954; bh=2Kj4QSySMoXs2QkLx9ebiSjqLXh2WU9gpXm1wBDX2jw=; h=Date:From:To:In-Reply-To:References:Subject:From; b=Ra6tPaiKYaVdrx/VoKLRDJ4EG4v/wF3umSNm9EjzUV6QPvgZNmvQERu51dkJEk26K 4hsuQFjrdgyVC5z6lwNhZkqYkvig7Bc/ziW7yrszRM3E4PUPMrSeayqiyJZ5F8lScb gsVAI5XkDx8kCcG65zolbv4FJRB9nx+W3iOgTIIabrdUxeBNc02/X/kwSNud1nJAz+ HQU8yLw4uHRSV8K+CJj2FVpQvqT9UOhnHZjvmpdLoanfXlG6p8boeCU/z1Y33qWlol g2XZcyvNY1mpmT2sVEvfuM3IOWtfI7IDwhnQHWNTdmhgKL7aUxmOzWhxac7FbMGCKG cGvrASwETpAwg== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id EE886180388 for ; Wed, 14 May 2025 21:25:52 +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.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_MISSING,HTML_MESSAGE, RCVD_IN_DNSWL_LOW,SPF_HELO_PASS,SPF_PASS 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 fhigh-a7-smtp.messagingengine.com (fhigh-a7-smtp.messagingengine.com [103.168.172.158]) (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 ; Wed, 14 May 2025 21:25:42 +0000 (UTC) Received: from phl-compute-05.internal (phl-compute-05.phl.internal [10.202.2.45]) by mailfhigh.phl.internal (Postfix) with ESMTP id 075FD11400A1 for ; Wed, 14 May 2025 17:27:53 -0400 (EDT) Received: from phl-imap-09 ([10.202.2.99]) by phl-compute-05.internal (MEProxy); Wed, 14 May 2025 17:27:53 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bottled.codes; h=cc:content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:subject :subject:to:to; s=fm1; t=1747258073; x=1747344473; bh=g+QoqGq5QU fuzqiWrh/Htpr9/w7Esp1hN+LQuYz+ZVI=; b=GV6W3etUn/ozdsmE+QMGj2SNLB 6MWcFXiFsRe9OfZal9NJVKjA+n1+SE9iyiTYN5WAMLLARb/VKnI5IvyIy3rW0rQ5 W+PFFQxdlAZ9m5u0qF1APANg6S9NA49C0yrX6PX5m1L7fQ89ddH5aZPZY55Q/WND xhtNtAAXvV1Go1d2YVHalrPsJ2e/kX/ZFKJeUETkx1EJp6knimHK98bk47If2cNS pShnYS9iOwjbkYxwmhvxPCIKAoH4HfcqceH8YKU2zRB1r5+ffKM05mRUYR45HzrN oFuXGdgbA5B4Oefdbuq9THHTI8x297AIEFmEAUksedgEEIH5glB9j8RoqJpQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:subject:subject:to :to:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm3; t= 1747258073; x=1747344473; bh=g+QoqGq5QUfuzqiWrh/Htpr9/w7Esp1hN+L QuYz+ZVI=; b=rZvCWsvv5rjqMr0Oe3KOvy0L2mAPHxgADaIGGjR+5RORWfGh7Vj +wSld8N11+2j8b9jPSkFcFO+4w3L6cgSb8gF745KtrJaNu5qCTeku92veZOBU3os +WmVerg8qWPZNdpA3ykMi96Id30IO6WwcMBX2pXaNH+A8RJN3N6k7xNN7FMoZRQi wehEZCMF5+KQe36A0BpuvdCtDKVWxROkXmLVbvheF7dXgNNN873bAjthV+DsnrwO WFxlSGZq31Yqj5sKYyV+QFnsPQcwjIae6eAtsFOFsB4lY/TuCN7qf+mPP6kg21WN q5xI5d64csIWVVO+x3kWuinGowRqQTJ3UNQ== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefvddrtddtgdeftdektdeiucetufdoteggodetrf dotffvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdggtfgfnhhsuhgsshgtrhhisggv pdfurfetoffkrfgpnffqhgenuceurghilhhouhhtmecufedttdenucenucfjughrpefogg ffhffvkfgjfhfutgesrgdtreerredtjeenucfhrhhomhepfdftohgsucfnrghnuggvrhhs fdcuoehrohgssegsohhtthhlvggurdgtohguvghsqeenucggtffrrghtthgvrhhnpedtue ejtdethfeulefhtdelieduteelffdtudelheffgedtieehhfelieejgfevgeenucevlhhu shhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehrohgssegsohhtth hlvggurdgtohguvghspdhnsggprhgtphhtthhopedupdhmohguvgepshhmthhpohhuthdp rhgtphhtthhopehinhhtvghrnhgrlhhssehlihhsthhsrdhphhhprdhnvght X-ME-Proxy: Feedback-ID: ifab94697:Fastmail Received: by mailuser.phl.internal (Postfix, from userid 501) id 9C4EE302005D; Wed, 14 May 2025 17:27:52 -0400 (EDT) X-Mailer: MessagingEngine.com Webmail Interface Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net x-ms-reactions: disallow MIME-Version: 1.0 X-ThreadId: T018bd9ffc60205f7 Date: Wed, 14 May 2025 23:27:32 +0200 To: internals@lists.php.net Message-ID: <9f6a0d6e-27c3-4f77-aed6-e55147442b6f@app.fastmail.com> In-Reply-To: <9A26F72B-D0EF-414F-B193-BED3CAB26A0B@rwec.co.uk> References: <3ae9a6ea-f135-472b-b2bf-e6cd6ebad299@app.fastmail.com> <9A26F72B-D0EF-414F-B193-BED3CAB26A0B@rwec.co.uk> Subject: Re: [PHP-DEV] Module or Class Visibility, Season 2 Content-Type: multipart/alternative; boundary=05eab717150b44caabef613c2400afb1 From: rob@bottled.codes ("Rob Landers") --05eab717150b44caabef613c2400afb1 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable On Wed, May 14, 2025, at 16:57, Rowan Tommins [IMSoP] wrote: >=20 >=20 > On 14 May 2025 14:24:57 BST, Michael Morris wrote: > >Well, it's what Go calls "modules". It's confusing because I was being > >truthful, not snarky, when I said "Ask 10 programmers for the definit= ion of > >module and expect 12 answers." I'm self trained, so I expect to get = my > >terms wrong from time to time. But I know enough to identify problems= and > >needs and I've tried to be clear on that. >=20 > I don't know much about Go, but at a glance it uses a similar model to= JavaScript and Python where *classes don't have a universal name*, the = names are always local. That's not a different kind of module, it's a fu= ndamentally different *language design*. Go has some weird scoping, for sure. Everything is done by convention in= stead of syntax. In other words, if you want to export a symbol, you cap= italize it; otherwise, it is lower-cased and thus private to the module.= Then each directory is a module, and even in the same project, you cann= ot access another lower-cased symbol from another directory -- er, modul= e. It is strange, and I don't think it translates to PHP. PHP is generally = explicit via syntax over convention. >=20 > If you want to use two different versions of Guzzle in the same applic= ation, the first problem you need to solve has nothing to do with requir= e, or autoloading, or Phar files. The first problem you need to solve is= that you now have two classes called \GuzzleHttp\Client, and that break= s a bunch of really fundamental assumptions.=20 As written, that simply isn't possible in PHP because there is only one = class allowed with a given name. Names of classes are global. I don't th= ink this has to be the case, though. Different languages take different = approaches to this. For example, JavaScript allows each module to "close= over" its dependencies so each module can import its own version of dep= endencies. Originally, there wasn't even any deduplication, so you'd hav= e 500 copies of left-pad or whatever. Then there is Go, which doesn't al= low you to have multiple versions of modules. You get exactly one versio= n, which is similar to how PHP currently works with composer by default.= However, with some massaging, you can "prefix" your imports so you get = only your own version. I believe many WordPress plugins do this, so each= plugin can use their own version of things. I'm fairly certain we can do a similar thing so that each module gets it= s own unique 'namespace' in the class table such that two modules can de= fine the same classes. So ModuleA and ModuleB can have Foo\Bar without c= onflicting with one another. From the user's perspective, we can probabl= y hide that technical detail from them but allow aliasing: use module ModuleA; // import ModuleA's namespace into our current names= pace for this file use module ModuleB as Baz; // import ModuleB's namespace into our curren= t namespace for this file, but with a prefix Foo\Bar; // ModuleA\Foo\Bar Baz\Foo\Bar; // ModuleB\Foo\Bar I'm just spitballing syntax here, and I'm not suggesting it actually wor= k like this, but I just want to illustrate that I think there are reason= able ways to allow modules to have conflicting names. > For example:=20 > - plugin1 uses Guzzle v5, runs "$client1 =3D new \GuzzleHttp\Client", = and returns it to the main application > - The main application passes $client1 to plugin2 > - plugin2 uses Guzzle v4 > plugin2 runs "$client2 =3D new \GuzzleHttp\Client" >=20 > $client1 and $client2 are instances of different classes, with the sam= e name! How does "instanceof" behave? What about "get_class"? What if yo= u serialize and unserialize? I'm of the opinion that the "names" of the module classes be distinct so= that humans (and deserializers) know it is from a module. Something lik= e [ModuleA]\Foo\Bar. >=20 > I think if you changed the language enough that those questions didn't= matter, it would be a language fork on the scale of Python 2 to 3, or e= ven Perl 5 to Raku (originally called "Perl 6"). Every single applicatio= n and library would have to be rewritten to use the new concept of what = a class is. And most of them would get absolutely no benefit, because th= ey *want* to reference the same version of a class everywhere in the app= lication. I suspect the hard part will be defining the module in the first place. = IE, the "package.json" or "go.mod" or whatever it gets called. As compos= er isn't a part of the PHP project, I don't want to take it for granted,= but I also don't want to rely on it. That means each module may have to= define its own "loader" or somehow define what PHP files encompass the = module. As I mentioned earlier, PHP doesn't usually operate by conventio= n, though the community tends to force it to anyway (PSR-4 autoloading c= omes to mind immediately); so we'd need something that is explicit but a= utomatable so the community can implement conventions. That's going to be the hard part. >=20 > That's why I think "containers" are the more useful comparison - you n= eed some way to put not just plugin1 itself, but all the third-party cod= e it calls, into some kind of sandbox, as though it was running in a sep= arate process. If you can control what classes can go into and out of th= at sandbox, then in any piece of code, you don't end up with conflicting= meanings for the same name - just as a Linux container can't open a net= work port directly on the host. Exactly. >=20 > Regards, > Rowan Tommins > [IMSoP] >=20 =E2=80=94 Rob --05eab717150b44caabef613c2400afb1 Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: quoted-printable


On Wed, May 14, 2025, at 16:57, Rowan Tommins [IMSoP] = wrote:


On 14 May 2025 14:24:57 BST, Michael Morris <tendoaki@gmail.com> wrote:
>Well, it's what Go calls "modules". It's confusing because I= was being
>truthful, not snarky, when I said "Ask 10 progr= ammers for the definition of
>module and expect 12 answers.= "  I'm self trained, so I expect to get my
>terms wron= g from time to time. But I know enough to identify problems and
>needs and I've tried to be clear on that.

I don't know much about Go, but at a glance it uses a similar model to = JavaScript and Python where *classes don't have a universal name*, the n= ames are always local. That's not a different kind of module, it's a fun= damentally different *language design*.

Go has some weird scoping, for sure. Everything is done by convent= ion instead of syntax. In other words, if you want to export a symbol, y= ou capitalize it; otherwise, it is lower-cased and thus private to the m= odule. Then each directory is a module, and even in the same project, yo= u cannot access another lower-cased symbol from another directory -- er,= module.

It is strange, and I don't think it tr= anslates to PHP. PHP is generally explicit via syntax over convention.

<= br>
If you want to use two different versions of Guzzle in the= same application, the first problem you need to solve has nothing to do= with require, or autoloading, or Phar files. The first problem you need= to solve is that you now have two classes called \GuzzleHttp\Client, an= d that breaks a bunch of really fundamental assumptions. 

As written, that simply isn't possible in P= HP because there is only one class allowed with a given name. Names of c= lasses are global. I don't think this has to be the case, though. Differ= ent languages take different approaches to this. For example, JavaScript= allows each module to "close over" its dependencies so each module can = import its own version of dependencies. Originally, there wasn't even an= y deduplication, so you'd have 500 copies of left-pad or whatever. Then = there is Go, which doesn't allow you to have multiple versions of module= s. You get exactly one version, which is similar to how PHP currently wo= rks with composer by default. However, with some massaging, you can "pre= fix" your imports so you get only your own version. I believe many WordP= ress plugins do this, so each plugin can use their own version of things= .

I'm fairly certain we can do a similar thing = so that each module gets its own unique 'namespace' in the class table s= uch that two modules can define the same classes. So ModuleA and ModuleB= can have Foo\Bar without conflicting with one another. From the user's = perspective, we can probably hide that technical detail from them but al= low aliasing:

use module ModuleA; // import Mod= uleA's namespace into our current namespace for this file
use = module ModuleB as Baz; // import ModuleB's namespace into our current na= mespace for this file, but with a prefix

Foo\Ba= r; // ModuleA\Foo\Bar
Baz\Foo\Bar; // ModuleB\Foo\Bar

I'm just spitballing syntax here, and I'm not suggestin= g it actually work like this, but I just want to illustrate that I think= there are reasonable ways to allow modules to have conflicting names.

F= or example: 
- plugin1 uses Guzzle v5, runs "$client1 =3D= new \GuzzleHttp\Client", and returns it to the main application
- The main application passes $client1 to plugin2
- plugin2= uses Guzzle v4
plugin2 runs "$client2 =3D new \GuzzleHttp\Cli= ent"

$client1 and $client2 are instances of dif= ferent classes, with the same name! How does "instanceof" behave? What a= bout "get_class"? What if you serialize and unserialize?

I'm of the opinion that the "names" of the module= classes be distinct so that humans (and deserializers) know it is from = a module. Something like [ModuleA]\Foo\Bar.


I think if yo= u changed the language enough that those questions didn't matter, it wou= ld be a language fork on the scale of Python 2 to 3, or even Perl 5 to R= aku (originally called "Perl 6"). Every single application and library w= ould have to be rewritten to use the new concept of what a class is. And= most of them would get absolutely no benefit, because they *want* to re= ference the same version of a class everywhere in the application.
=

I suspect the hard part will be definin= g the module in the first place. IE, the "package.json" or "go.mod" or w= hatever it gets called. As composer isn't a part of the PHP project, I d= on't want to take it for granted, but I also don't want to rely on it. T= hat means each module may have to define its own "loader" or somehow def= ine what PHP files encompass the module. As I mentioned earlier, PHP doe= sn't usually operate by convention, though the community tends to force = it to anyway (PSR-4 autoloading comes to mind immediately); so we'd need= something that is explicit but automatable so the community can impleme= nt conventions.

That's going to be the hard par= t.


That's why I think "containers" are the more useful co= mparison - you need some way to put not just plugin1 itself, but all the= third-party code it calls, into some kind of sandbox, as though it was = running in a separate process. If you can control what classes can go in= to and out of that sandbox, then in any piece of code, you don't end up = with conflicting meanings for the same name - just as a Linux container = can't open a network port directly on the host.
<= br>
Exactly.


Regards,
Rowan Tommins
[IMSoP]


=E2=80=94 Rob
--05eab717150b44caabef613c2400afb1--