Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:127524 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 2979A1A00BC for ; Sun, 1 Jun 2025 16:09:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1748794019; bh=PTe1IFb+/Ew4Se6QcdOq/DNUotXQQEZARtL7jv9eN3I=; h=References:In-Reply-To:From:Date:Subject:To:From; b=H/Usq5EBYPafaLSLaTwR3mK3PpMVyTt36CfF+x+mmOvaD3UImzgK9HIXVVTh2H7j3 I8Rp80C3vGqBX/sNtxKz2G5rdKdv+1sMJh9jYuPHzN5OXqfGSjJGb6cAF7hFOmOlXT 9KVWnoGN1R59XaQ8MrNZnijNHD+wuZ2sDCr4MNKLiu1BHWhEnb6eNUTzn1GmRGOFcC UJLcPMYMI5rTDIJYiRgwWgriS0k53DsttngvAzbiSi1nbJhpvdb9RVDcnAGM1Z+7qZ wLqkmpGQOZ+Kgu2FYs1hBKps0C3ghrQ8AF0uWcG7JuemUVSfeC1EORbud0QhGCbzuL alYr8iDK2ulnw== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id C7D261801DA for ; Sun, 1 Jun 2025 16:06:56 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-0.4 required=5.0 tests=BAYES_50,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_PASS,FREEMAIL_FROM, HTML_MESSAGE,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE, SPF_PASS autolearn=no autolearn_force=no version=4.0.1 X-Spam-Virus: Error (Cannot connect to unix socket '/var/run/clamav/clamd.ctl': connect: Connection refused) X-Envelope-From: Received: from mail-qv1-f54.google.com (mail-qv1-f54.google.com [209.85.219.54]) (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 ; Sun, 1 Jun 2025 16:06:54 +0000 (UTC) Received: by mail-qv1-f54.google.com with SMTP id 6a1803df08f44-6facb09ea08so54192536d6.3 for ; Sun, 01 Jun 2025 09:08:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1748794138; x=1749398938; darn=lists.php.net; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :from:to:cc:subject:date:message-id:reply-to; bh=rFbiIQle9AJQv+dJx54NODegzkEYEhEgVuGXYrVivv4=; b=Ibg9iyfyi41sttsTKpB5WSTij8O89ykSJdvk9MqrBy/gnmpTR0X8y65Ku8vdZ2fY05 2LTKuRWww0lYlwUJ0eK+xlQj6fepOdy0w5WK97fIMsx+H74Va0DI96S8LuHl7R8WbhQW 1ducQvm5eelt/SikAI9G5OluRBVDvI1PZ4rv9Lgt+dlYvLeeS3Hmoh6dvqjAQHeuxVjG uCnfLzCcweUaCT2FQFq3VxksWMVUQikVw1ZKAnF3uXS2FxI6SEu1v9xPVhPLLsbncmUi IRz+HvhnXnVXqPf68oTnrbWN9JzjIiAglhRBoKGnrZPrQHqWDdQiJ2UfO8eQ0v5wCjyt CSRg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1748794138; x=1749398938; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=rFbiIQle9AJQv+dJx54NODegzkEYEhEgVuGXYrVivv4=; b=XJ3+GbRPDY/mjf24CABJRLo586zHrytHfVRA/375Tnlrm//xDlE1mOe8rg5VqDIar6 qCXXno8qQsNIN+7dGNk46Lo37oEHOdGeCWoodJd3EYMDvcxXwxyyMnqyYdM8cCEnK6KO PPoAWN3/e35pMK+/mH3CaJLKqAfGnW2wTNOpnSj/n34yArUWJEq3GzZ79qyWsyz613Cw vBpmPlhqlvyKfkKCwinQPGBXC4EUoRWrP6bZJjd8b4JYKSrNpA2+W2NjL9C8KIqhG/bg 5kvBAC3YrX3Fy32RKast73A2LeWXvCoM0TjckLJYiUBLvIN2G2dJK2/Os0JVQsN2ue1m 1dsg== X-Gm-Message-State: AOJu0YxbEKb9LVXIYBfhCsCPSySVpuMQ28Xx4wDdsnW+N8whCPMaLCGS KplZDzxIeMDVWwxYc3MxHhfZjNn+w8ReVDvh6nhGFdf/Bq10Hbcw6+D1F5QgcOmEWjZ7GZA8nMy Wloh7WjBVHlsI9KAApQDU7jNaF96droRAp7iV X-Gm-Gg: ASbGncvymUP5QEZQ44nDtSFnDWpttt1194S9jxTTMtFXjgFTroLrsdNXGHYAZDnHBLh kXzaKNTc2uzxo/fAn8V4YlBNyFVaYEkU9dGMVnl7/5HPSmFJeV8HsziNz7PnZ62n/2Ha6YCd85S Z7ZKobPLJebKKK8/S3oLzo0vJ3DOO0YJuZtOOwbrSd/B4xrpTO+BKHQ6cbvZtQ1vf2AJGEaL6es w== X-Google-Smtp-Source: AGHT+IFOeqC0XFTXmheA1uTa754Qc2/W9XUax2fw+xSPX6s3Ik93I9JAwGr9WV4Tdxzxpi+QsWsmFt6Vy4nwVrwnKbE= X-Received: by 2002:a05:6214:d66:b0:6f8:997d:fc82 with SMTP id 6a1803df08f44-6fad18f3b13mr135330666d6.3.1748794138452; Sun, 01 Jun 2025 09:08:58 -0700 (PDT) Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net x-ms-reactions: disallow MIME-Version: 1.0 References: <78641D8B-AF1D-4912-920A-D75A37C32F05@rwec.co.uk> <354cb888-97c4-4f8c-a0da-359d1e63c0f9@rwec.co.uk> <10D95B6E-094B-4EAE-A18A-AF6B795CB352@rwec.co.uk> <2adbff61-5e11-4d39-ab5c-d7950a4550a6@app.fastmail.com> <79E7FA26-2F5A-470C-B1DF-12CC46A08FE5@rwec.co.uk> <1c6dcd84-9016-48e1-971f-de7749cbdce8@rwec.co.uk> <44F59416-3922-4AF4-881A-C64F2C4E9345@rwec.co.uk> <7F11844A-A98C-4843-BC94-815FBCD2B73F@garsi.de> <7840468C-F60C-4A44-AE40-16F9007EF428@rwec.co.uk> <160E9B1D-9AF6-479B-A628-A73C618D7C1B@garsi.de> <6cbfb0ca-5be3-4c00-94ba-4595cfad3738@app.fastmail.com> In-Reply-To: <6cbfb0ca-5be3-4c00-94ba-4595cfad3738@app.fastmail.com> Date: Sun, 1 Jun 2025 12:08:46 -0400 X-Gm-Features: AX0GCFvOATwt0OgXs4LOodNNfen1b0MRfKoLlx4DuSi3ex4jnJhALpP7uT0vW90 Message-ID: Subject: Re: [PHP-DEV] Module or Class Visibility, Season 2 To: internals@lists.php.net Content-Type: multipart/alternative; boundary="000000000000686961063684dd0b" From: tendoaki@gmail.com (Michael Morris) --000000000000686961063684dd0b Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Sun, Jun 1, 2025 at 3:18=E2=80=AFAM Rob Landers wrot= e: > This could work! I have a couple of critiques, but they aren=E2=80=99t ne= gative: > > I think I like it. It might be worth pointing out that JavaScript "hoists= " > the imports to file-level during compilation =E2=80=94 even if you have t= he import > statement buried deep in a function call. Or, at least it used to. I > haven=E2=80=99t kept track of the language that well in the last 10 years= , so I > wouldn=E2=80=99t be surprised if it changed; or didn=E2=80=99t. I don=E2= =80=99t think this is > something we need to worry about too much here. > As I pointed out in detail to Rob off list JavaScript has 2 import mechanisms that are subtly different from each other. Those interested can read here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statement= s/import https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators= /import > It=E2=80=99s also worth pointing out that when PHP compiles a file, every= file has > either an explicit or implicit return. > https://www.php.net/manual/en/function.include.php#:~:text=3DHandling%20R= eturns%3A,from%20included%20files > . > True, but it's a rarely used mechanism and a return statement isn't required - hence an implicit return is possible. > > So, in other words, what is it about require_module that is different fro= m > `require` or `include`? Personally, I would then change PHP from "compile > file" mode when parsing the file to "compile module" mode. From a totally > naive point-of-view, this would cause PHP to: > > 1. if we already have a module from that file; return the module > instead of compiling it again. > 2. swap out symbol tables to the module=E2=80=99s symbol table. > 3. start compiling the given file. > 4. concatenate all files as included/required. > 5. compile the resulting huge file. > 6. switch back to the calling symbol table (which may be another > module). > 7. return the module. > > For a v1, I wouldn=E2=80=99t allow autoloading from inside a module =E2= =80=94 or any > autoloaded code automatically isn=E2=80=99t considered to be part of the = module (it > would be the responsibility of the main program to handle autoloading). > This is probably something that needs to be solved, but I think it would > need a whole new approach to autoloading which should be out of scope for > the module RFC (IMHO). > > In other words, you can simply include/require a module to load the entir= e > module into your current symbol table; or use require_module to "contain" > it. > Yes, that is certainly possible but comes at an opportunity cost from an engine design standpoint. This is an exceedingly rare opportunity to go back and fix mistakes that have dogged the language for sometime that simply can't be fixed without creating large backwards compatibility problems. For instance, say for the sake of example that PHP files could be compiled 10 times faster if the object parser could assume the whole file was code and there's not going to be any tags or Heredoc or Nowdoc blocks. It might be worth it then to have modules not allow such, and if an author had a block of code that they really wanted this templating behavior to apply to they still could issue a require. Maybe it's time to dig up some downvoted RFC's that got killed for these reasons. > > As for what should a module return? I like your idea of just returning an > object or closure. > I'm leaning towards something akin to a static class. If modules have export keywords (note that if they have their own parser they can also have keywords without disrupting the existing PHP ecosystem) then compiling one would be a static class with members and methods matching what was exported= . > I just had another thought; sorry about the back-to-back emails. This > wouldn=E2=80=99t preclude something like composer (or something else) fro= m being > used to handle dependencies, it would just mean that the package manager > might export a "Modules" class + constants =E2=80=94 we could also write = a composer > plugin that does just this: > require_once 'vendor/autoload.php'; > $module =3D require_module Vendor\Module::MyModule; > where Vendor\Module is a generated and autoloaded class containing consts > to the path of the exported module. That leads into some thoughts I have on loading modules in general. require_module is the simplest expression. That said, 'use module' might also be appropriate. require_once 'vendor/autoload.php'; use module Vendor/Module as MyModule; Something like that? JavaScript has a distinction between global scope import, which is almost analogous to our namespaces and use statement, and dynamic scope import, which is almost analogous to our require statements. Don't know if it's useful to us to draw such a distinction. --000000000000686961063684dd0b Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable


On Sun, Jun 1, = 2025 at 3:18=E2=80=AFAM Rob Landers <rob@bottled.codes> wrote:
<= blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-l= eft:1px solid rgb(204,204,204);padding-left:1ex">
This could work!= I have a couple of critiques, but they aren=E2=80=99t negative:
=
I think I like it. It might be worth pointing out that JavaS= cript "hoists" the imports to file-level during compilation =E2= =80=94 even if you have the import statement buried deep in a function call= . Or, at least it used to. I haven=E2=80=99t kept track of the language tha= t well in the last 10 years, so I wouldn=E2=80=99t be surprised if it chang= ed; or didn=E2=80=99t. I don=E2=80=99t think this is something we need to w= orry about too much here.

As I = pointed out in detail to Rob off list JavaScript has 2 import mechanisms th= at are subtly different from each other. Those interested can read here:


It=E2=80=99s also worth pointing out that when= PHP compiles a file, every file has either an explicit or implicit return.= =C2=A0https:/= /www.php.net/manual/en/function.include.php#:~:text=3DHandling%20Returns%3A= ,from%20included%20files.

T= rue, but it's a rarely used mechanism and a return statement isn't = required - hence an implicit return is possible.
=C2=A0

So, = in other words, what is it about require_module that is different from `req= uire` or `include`? Personally, I would then change PHP from "compile = file" mode when parsing the file to "compile module" mode. F= rom a totally naive point-of-view, this would cause PHP to:
    if we already have a module from that file; return the module instead of = compiling it again.
  1. swap out symbol tables to the module=E2=80=99s = symbol table.
  2. start compiling the given file.
  3. concatenate a= ll files as included/required.
  4. compile the resulting huge file.
  5. switch back to the calling symbol table (which may be another module).=
  6. return the module.
For a v1, I wouldn=E2=80=99t allo= w autoloading from inside a module =E2=80=94 or any autoloaded code automat= ically isn=E2=80=99t considered to be part of the module (it would be the r= esponsibility of the main program to handle autoloading). This is probably = something that needs to be solved, but I think it would need a whole new ap= proach to autoloading which should be out of scope for the module RFC (IMHO= ).

In other words, you can simply include/require = a module to load the entire module into your current symbol table; or use r= equire_module to "contain" it.

<= /div>
Yes, that is certainly possible but comes at an opportunity cost = from an engine design standpoint. This is an exceedingly rare opportunity t= o go back and fix mistakes that have dogged the language for sometime that = simply can't be fixed without creating large backwards compatibility pr= oblems. For instance, say for the sake of example that PHP files could be c= ompiled 10 times faster if the object parser could assume the whole file wa= s code and there's not going to be any <?php ?> tags or Heredoc o= r Nowdoc blocks.=C2=A0 It might be worth it then to have modules not allow = such, and if an author had a block of code that they really wanted this tem= plating behavior to apply to they still could issue a require. Maybe it'= ;s time to dig up some downvoted RFC's that got killed for these reason= s.=C2=A0
=C2=A0

As for what should a module return? I like y= our idea of just returning an object or closure.

I'm leaning towards something akin to a static cl= ass.=C2=A0 If modules have export keywords (note that if they have their ow= n parser they can also have keywords without disrupting the existing PHP ec= osystem) then compiling one would be a static class with members and method= s matching what was exported.


I just had another thought; sorry about the ba= ck-to-back emails. This wouldn=E2=80=99t preclude something like composer (= or something else) from being used to handle dependencies, it would just me= an that the package manager might export a "Modules" class + cons= tants =E2=80=94 we could also write a composer plugin that does just this:<= br>require_once 'vendor/autoload.php';
$module =3D require_modul= e Vendor\Module::MyModule;
where Vendor\Module is a generated and autolo= aded class containing consts to the path of the exported module.

That leads into some thoughts I have on loading modul= es in general.=C2=A0 require_module is the simplest expression.=C2=A0 That = said, 'use module' might also be appropriate.

<= div>require_once 'vendor/autoload.php';

us= e module Vendor/Module as MyModule;

Something like= that?

JavaScript has a distinction between global= scope import, which is almost analogous to our namespaces and use statemen= t, and dynamic scope import, which is almost analogous to our require state= ments.=C2=A0 Don't know if it's useful to us to draw such a distinc= tion.
--000000000000686961063684dd0b--