Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:124010 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 ADEB51A009C for ; Sat, 29 Jun 2024 07:07:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1719644901; bh=SKbZttwxi1k0Mf6m2TcZLIIYjQ4mXPQZf2kEkjNh21I=; h=From:Subject:Date:In-Reply-To:Cc:To:References:From; b=hgmTxLqwhNEgs2bBhoinMM8HEmbU4JENj8JGLQ0F6hBCSSrfVYqDKqfZwlskcwF6G 8YO2kNBmNQpJJxB1MpiPcP3Pc7PelDUXFzIa4OCPfU6Iq/Mw/F3jaMBXaaULLnbGCh Ft/EztYZoAVC/jw4GLCvDmnTa3wRPN3IDkfMcIjCF+PUy631mcpmU4+1ZWoAQqOK8E BQ3d4peMhKxWekR8gn7+/U2wES96pOjD7H4N9aAYe2FfFzmmT98bo6RHk7TCSfbhwL lHwLk6r+2ARI2q7mvVjgnwT/bJbCIjIgFl5s2ExoAN217PLeSHbYiwenegnOMmx2tB V8nWhb5yoNIAg== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 583A8180689 for ; Sat, 29 Jun 2024 07:08:20 +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=0.8 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,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-f178.google.com (mail-yw1-f178.google.com [209.85.128.178]) (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 07:08:19 +0000 (UTC) Received: by mail-yw1-f178.google.com with SMTP id 00721157ae682-64b9f11b92aso7978587b3.1 for ; Sat, 29 Jun 2024 00:07:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=newclarity-net.20230601.gappssmtp.com; s=20230601; t=1719644820; x=1720249620; 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=o648Zc4B4UVtT87q/ysyZThcd6tm+iNucP5iu49e9ys=; b=Eg1hT+jauiRntutoSZBx96uJ9hRsQniKafi/SpA/ZBpJaXT+y6N/XlRqPEWC606gH2 gOy9fbXFTnzlDJ5cWIcAvJgCUk6mK4WbdpoLB/iDtQvbewE2Wm0BxaHUQx/l5vB8KiMy /6ZWJI5eYAowbAg9Yy0IBXoWeLahKdf7pnRxtmTOSeyJj6G2t7PL+SUDtNutsNnlVB05 Jw8stQx0PKzV/gaHhtIbMkIrmNrQO4ANoLRUzjh0z5fy0fWCZ+QSJu+58OItqo/zk5y0 0Dy11EZzK3Ny0d1kVFpTig4CjXfGGMiAQa+u7bVAiQUiZtHugrf0Kozs7BVrDp7fCG2q 9nZg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1719644820; x=1720249620; 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=o648Zc4B4UVtT87q/ysyZThcd6tm+iNucP5iu49e9ys=; b=PqtN1iGQtS3rB5tnsC5IFp+eoy6hwEolL5ax7gHPM5DZ4VcLZgHqiAeyS/M4puDPI2 SjsIoQP5/N9GyGi6nzoG69LqEpjfsGnq8t1373c93RDKsKI7T8bAS9QpJXBV6hJElnb8 u9/Xf1OTMj2PAIsJibhROnSB+oFq3fgzIJ5GesrE013tZYmiLTMZYiyQzEi8DLWBiTXI qeVXQDnrqctNJaKIs12EFeOwOAOZK6YQTLvtblXGrBqk9XXtkyqaOeZOB8AF31t1uj+y fdGFEetJgwyGtUooa0TqypnxYGzuEYkeuKPNFJ+7DxAOg6/zd0YRAT2Gd9H5+LsZn9jV 5CEQ== X-Gm-Message-State: AOJu0YxGbyTmLJq00/r0xH9sG0PyXsILECYwRV3RZYNP+ogDtcCgqzS2 YhYjDPybsc+MI0+VjTKVsOuW2UHixfWcK4dnN4+EqYmBTD4eqbSsM6yYrOkSgkk= X-Google-Smtp-Source: AGHT+IGMesCyUkYpb50cU914LVU4hnIiraDkDJWZBYEOvsJQfW6TMNJ296lFb/8BrV0EPoOIrCKfCA== X-Received: by 2002:a05:690c:705:b0:62a:547:eaf2 with SMTP id 00721157ae682-64c72d40312mr3761197b3.39.1719644819643; Sat, 29 Jun 2024 00:06:59 -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-64a9a23c659sm6021787b3.51.2024.06.29.00.06.57 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sat, 29 Jun 2024 00:06:58 -0700 (PDT) Message-ID: Content-Type: multipart/alternative; boundary="Apple-Mail=_74499F48-6305-450A-92BF-A79571A79B6A" 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 03:06:57 -0400 In-Reply-To: Cc: PHP internals To: Michael Morris References: <0acedb8e-34be-4348-907b-4075cf7641fd@app.fastmail.com> <9c20b078-f82a-47fe-af23-2f3cdd233079@app.fastmail.com> X-Mailer: Apple Mail (2.3696.120.41.1.8) From: mike@newclarity.net (Mike Schinkel) --Apple-Mail=_74499F48-6305-450A-92BF-A79571A79B6A Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 > On Jun 28, 2024, at 3:07 AM, Michael Morris = wrote: > On Thu, Jun 27, 2024 at 8:16=E2=80=AFPM Mike Schinkel = > wrote: > node_modules IMO is one of the worse things about the JavaScript = ecosystem. Who has not seen the meme about node_modules being worse than = a black hole? >=20 > Fair enough. Or maybe import maps would be a better way forward. Import maps are really a small part of what PHP actually needs. For = example, is it a class, an interface, or a function? For a module, it is = a property? =20 I envision basically that this file, whatever it would be called would = be a pre-compilation of everything that PHP can pre-compile about the = files that are contained within the module/directory. See below where I talk about a pre-compiled `.php.module` > But ensuring that it is possible to disallow loading needs to be = contemplated in the design. PHP has to be able to know what is a module = and what isn't without expensive processes. >=20 > One possible solution is that if modules do not have tags, = ever, and someone directly tries to load a module through http(s) the = file won't execute. Only files with tags are executable by the = web sapi. Except that would require parsing all of the entire files in the = directory to know (unless everything were pre-compiled as I am = advocating.).=20 Still, I think it would be better to be explicit, and for that I would = propose the first line in the file needs to start with "module" and have = the name of the module. > I've only touched the surface on how GoLang does things. Some of it = was confusing to me at first. It's also been awhile so I'd need to = refresh my memory to speak to it. In Go modules or, in this context more correctly named "packages" are: - A collection of files grouped into a directory and thus all files in = that directory are in the same package. - Public or private scope are determined by case of symbols; lowercase = are private and uppercase are public. People coming from other languages = tend to hate this, but I have come to love it because it makes code less = dense while employing the same information as a "public" and "private" = keywords. It also makes code across different developers more = consistent. - Packages can be nested in package directories, but... - There is no concept of a "sub" package, meaning there are no = hierarchies when packages are used in code (there is a file path = hierarchy but that is only relevant for importing the package.) When I = started working with Go I thought that was unfortunate. Now after 5+ = years working with Go I see it as a really good decision. - Package files must have a "package" statement at the top, and all = files in the directory must have the same "package" statement, with one = caveat. - That caveat is that package files can have `package = _test` as a package name and that file is assumed to = contains a test but it cannot see private members in `package = `. =20 - Test files are typically named to pair with a `.go` and = would be named `_test.go`. That file's package name can = either be just `` or `_test`, depending on if = you want to reach into private members or not.=20 - You can also find `test` packages that contain all = `_test.go` files. - Testing is build into Go with `go test ./...` to run all tests in = current and all subdirectories. (Idiomatic testing in Go is so much = easier that idiomatic testing in PHP resulting in a culture of testing = among almost all Go developers.) - Package files can have `type`s, `var`s, `const`s, and `func`s as well = as imports and directives, of course.=20 - Types in Go can be `struct` (which is the closest Go has to a class), = slice of type e.g. `[]`, array of type e.g. `[]`, = `map[]`, and a few more that I won't go into as I think they = are out of scope for this explanation. - Packages can have one or more `init()` functions that are all called = before the program's `main()` func is called. There can also be multiple = `init()` functions even in the same file. - `var`s can be initialized and those initializations are run before the = program's `main()` func is called. - `const`s are initialized before the program's `main()` func is called = but can only be initialized by literal scalar types. Unfortunately. - `import`s take the form of `import ""` for standard library = types and where a `` can contain parent paths. - For local types `import`s take the form of `import = "/"` where a `` is defining by having a = `go.mod` file in the directory or a parent directory, and a `` = can contain parent paths. A `go.mod` file has a `module` directive, a = `go` version, and one or more `require` statements (I'm ignoring a bit = of minutia here.) - Modules allow grouping of packages together and were added in recent = years to provide versioning for the collective dependencies of a module. = The version information is stored in `go.sum` and is managed = automatically with Go CLI commands. - For external third party modules `import`s take the form of `import = "/"` where `` can contain parent paths and = almost always does. An example is "github.com/stretchr/testify/assert = " =20 - External modules are by definition HTTP(S) GETable, and Go developers = use `go get ` on the command line to download the module. Go = does not have or need a 3rd party package manager as that can become a = single point of failure and is definitely a single point of control. To = download `testify` for use in their Go module a Go dev would run `go get = github.com/stretchr/testify ` - Most external third party modules for Go are hosted on Github but can = be hosted on a custom domain, Bitbucket, GitLab, etc. - The Go team manages a standard proxy for `go get` but organizations = can run their own if desired. - `import`s are referenced by name internally where the package name is = the last segment of the import after a `/`, or just the name if no = slash. So "github.com/stretchr/testify/assert = " is referenced in code as = `assert`. For example, `assert.Equal(t,1,value)` would assert that = `value!=3D1` then it would use the testing variable `t` to mark this = assertion as an error and generate appropriate output. - `import`s can be aliases so you could `import check = "github.com/stretchr/testify/assert = "` and then call = `check.Equal(t,1,value) instead of `assert.Equal(t,1,value)` but needing = to alias a package frequently is a code smell for a badly named package. - You can use `.` as an alias and then not need to use the alias, so we = could `import ` "github.com/stretchr/testify/assert = "` and then just call = `Equal(t,1,value) instead of `assert.Equal(t,1,value)` but this is = frowned on in the Go community except for in very specific use-cares. - You can use `_` to bring in a package even if you are not referencing = it in case it has an `init()` function that you need to run. If that = applied to testify it would look like this: `import _ ` = "github.com/stretchr/testify/assert = ".` - All of `import`, `var`, and `const` support a multiline for using = parenthesis like so: var ( x =3D 1 y =3D 2 ) - Module names are idiomatically one word w/o underscores and lowercase. - There is no need to import specific symbols from a Go package like = there is in JavaScript. I have programmed in both Go and JS, and I have = not found a real benefit to having to reference everything explicitly in = the import =E2=80=94 since you have to mention the package name = everywhere you use any package symbol =E2=80=94 but I have noticed a = benefit to not having nearly as much boilerplate at the top of the file = for import when working with Go vs. working with Javascript. And my = GoLang IDE just manages imports for me whereas WebStorm just calls out = when I haven't imported function names in Javascript. I am sure there is more I missed, but that should cover the highlights. The takeaways that I think would be useful are PHP modules are: 1. Imports 2. Import aliases=20 3. Module-level consts 4. Module-level init() functions 5. Module-level vars with initialization 6. Module-level functions 7. One directory =3D=3D one module 8. No hierarchy for modules 9. Single word module names in lowercase. 10. Module sytax being , e.g. = mymodule->MySymbol Takeaways I wish the PHP community would consider but doubt there is any = chance: 1. Having modules be HTTP(S) GETtable with `php get ` 2. Uppercase being public, lowercase being private, and no need for = protected 3. Test packages with testing build into PHP e.g. `php test ./...` > >> I'm not fond of this either. > > > > There will need to be a way to define the entrypoint php. I think = index.php is reasonable, and if another entry point is desired it can be = called out -> "mypackage/myentry.php" >=20 > Why is an entry point needed? If there is a module metadata file as I = am proposing PHP can get all the information it needs from that file. = Maybe that is the `.phm` file? >=20 > Maybe. Again, I need to look over this meta data format. Also, how = does it get created? As I am envisioning, PHP at the command line would have the ability to = pre-compile a module =E2=80=94 aka all files in the module directory =E2=80= =94 and then write a module-specific file, maybe `.php.module`? That = could ideally be optimized for loading by PHP and have everything it = needs to know to run the code in that module. That file could be completely self-contained include all source code = similar to a `.phar` file, or it could just have a complete symbol table = and still require the PHP source code to exist as well. I have not = pondered all the pros and cons of these alternatives yet. Clearly though even if it compiled to a self-contained file the .PHP = files would still be needed during development. Thus I envision that = the PHP CLI would need a `--watch` option to watch directories and = recompile the `.php.module` file upon PHP file change. IDEs like = PhpStorm could run `php --watch` for users and non-IDE users could run = it themselves. When PHP would come across an `import` statement pointing to a module = directory it would first look for the compiled `.php.module` file and if = found use it but if not found it would recreate it. Maybe it could write = to disk, or generate an error if it cannot write to disk. OTOH writing = to disk might be a security issue in which case it could issue a warning = that the `.php.module` file does not exists and then compile the module = to memory and continue on. It would be nice if there was a mode where PHP would check the = timestamps of all PHP files in the module directory and if the compiled = `.php.module` was earlier than any of the .php file then recompile but = you'd want that off for production. That could be a new function = `set_dev_mode(boolean)` or a CLI option to create a `.phpdev.module` = instead of a `.php.module`. Clearly anyone using deployments could have their build generate all the = required `.php.module` files for deployment, and hosting companies that = host apps that don't use deployments like WordPress could have processes = that build the `.php.module` files for their users. I think I have thought through this enough to identify there are no = technical blockers, but I could certainly have missed something so = please call it out if anyone can identify something that would keep this = from working and/or significantly change the nature of PHP development. BTW, this pre-compiling would ONLY apply to modules, so people not using = modules would not have to be concerned about any of this at all. -Mike P.S.=20 > I remember when the choice to use \ was made. I've rarely been so = angry about a language design choice before or since. I've gotten used = to it, but seeing \\ all over the place in strings is still.. yuck. Ditto. --Apple-Mail=_74499F48-6305-450A-92BF-A79571A79B6A Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset=utf-8
On = Jun 28, 2024, at 3:07 AM, Michael Morris <tendoaki@gmail.com> = wrote:
On Thu, Jun = 27, 2024 at 8:16=E2=80=AFPM Mike Schinkel <mike@newclarity.net>= wrote:
node_modules IMO is one of the worse = things about the JavaScript ecosystem. Who has not seen the meme about = node_modules being worse than a black hole?

Fair enough. Or maybe import maps would be a better way = forward.
=

Import = maps are really a small part of what PHP actually needs. For example, is = it a class, an interface, or a function? For a module, it is a property? =  

I = envision basically that this file, whatever it would be called would be = a pre-compilation of everything that PHP can pre-compile about the files = that are contained within the module/directory.

See below where I talk about a pre-compiled = `.php.module`

 But ensuring that it is = possible to disallow loading needs to be contemplated in the design. PHP = has to be able to know what is a module and what isn't without expensive = processes.

One = possible solution is that if modules do not have <?php ?> tags, = ever, and someone directly tries to load a module through http(s) the = file won't execute. Only files with <?php ?> tags are executable = by the web = sapi.

Except that = would require parsing all of the entire files in the directory to know = (unless everything were pre-compiled as I am = advocating.). 

Still, I think it would be better to be = explicit, and for that I would propose the first line in the file needs = to start with "module" and have the name of the = module.

I've only touched the surface on = how GoLang does things. Some of it was confusing to me at first. It's = also been awhile so I'd need to refresh my memory to speak to = it.

In = Go modules or, in this context more correctly named "packages" = are:
=

- A collection of files grouped = into a directory and thus all files in that directory are in the same = package.

- Public or = private scope are determined by case of symbols; lowercase are private = and uppercase are public. People coming from other languages tend to = hate this, but I have come to love it because it makes code less dense = while employing the same information as a "public" and "private" = keywords. It also makes code across different developers more = consistent.

- Packages can = be nested in package directories, = but...

- There is no = concept of a "sub" package, meaning there are no hierarchies when = packages are used in code (there is a file path hierarchy but that is = only relevant for importing the package.) When I started working with Go = I thought that was unfortunate. Now after 5+ years working with Go I see = it as a really good decision.

- = Package files must have a "package" statement at the top, and all files = in the directory must have the same "package" statement, with one = caveat.

- That caveat is that = package files can have `package <packagename>_test` as a package = name and that file is assumed to contains a test but it cannot see = private members in `package <packagename>`.  

- Test files are typically named to pair with a = `<filename>.go` and would be named `<filename>_test.go`. =  That file's package name can either be just `<packagename>` = or `<packagename>_test`, depending on if you want to reach into = private members or not. 

- You = can also find `test` packages that contain all = `<filename>_test.go` files.

- = Testing is build into Go with `go test ./...` to run all tests in = current and all subdirectories. (Idiomatic testing in Go is so much = easier that idiomatic testing in PHP resulting in a culture of testing = among almost all Go developers.)

- Package files can = have `type`s, `var`s, `const`s, and `func`s as well as imports and = directives, of course. 

- Types = in Go can be `struct` (which is the closest Go has to a class), slice of = type e.g. `[]<type>`, array of type e.g. = `[<n>]<type>`, `map[<key>]<value>`, and a = few more that I won't go into as I think they are out of scope for this = explanation.

- Packages can have one = or more `init()` functions that are all called before the program's = `main()` func is called. There can also be multiple `init()` functions = even in the same file.

- `var`s can = be initialized and those initializations are run before the program's = `main()` func is called.

- `const`s = are initialized before the program's `main()` func is called but can = only be initialized by literal scalar types. = Unfortunately.

- `import`s take the = form of `import "<package>"` for standard library types and where = a `<package>` can contain parent paths.

- For local types `import`s take the form of = `import "<module>/<package>"` where a `<module>` is = defining by having a `go.mod` file in the directory or a parent = directory, and a `<package>` can contain parent paths.  A = `go.mod` file has a `module` directive, a `go` version, and one or more = `require` statements (I'm ignoring a bit of minutia here.)

- Modules allow grouping of packages together and = were added in recent years to provide versioning for the collective = dependencies of a module. The version information is stored in `go.sum` = and is managed automatically with Go CLI commands.

- For external third party = modules `import`s take the form of `import = "<domain>/<package>"` where `<package>` can contain = parent paths and almost always does. An example is "github.com/stretchr/testify/assert"  

- External modules are by definition HTTP(S) = GETable, and Go developers use `go get <module>` on the command = line to download the module. Go does not have or need a 3rd party = package manager as that can become a single point of failure and is = definitely a single point of control.  To download `testify` for = use in their Go module a Go dev would run `go get github.com/stretchr/testify`
=

- Most external = third party modules for Go are hosted on Github but can be hosted on a = custom domain, Bitbucket, GitLab, etc.

- The Go team manages a standard = proxy for `go get` but organizations can run their own if = desired.

- `import`s are referenced by name internally = where the package name is the last segment of the import after a = `/`, or just the = name if no slash.  So "github.com/stretchr/testify/assert" is referenced in code = as `assert`.  For example, `assert.Equal(t,1,value)` would assert = that `value!=3D1` then it would use the testing variable `t` to mark = this assertion as an error and generate appropriate = output.

- `import`s can be = aliases so you could `import check "github.com/stretchr/testify/assert"` and then call = `check.Equal(t,1,value) instead of `assert.Equal(t,1,value)` but needing = to alias a package frequently is a code smell for a badly named = package.

- = You can use `.` as an alias and then not need to use the alias, so we = could `import ` "github.com/stretchr/testify/assert"` and then just call = `Equal(t,1,value) instead of `assert.Equal(t,1,value)` but this is = frowned on in the Go community except for in very specific = use-cares.

- You can = use `_` to bring in a package even if you are not referencing it in case = it has an `init()` function that you need to run.  If that applied = to testify it would look like this: `import _ ` "github.com/stretchr/testify/assert".`

- All of `import`, `var`, and `const` support a = multiline for using parenthesis like so:

var (
x = =3D 1
        y =3D 2
= )

- Module names are = idiomatically one word w/o underscores and lowercase.

- There is no need to import specific symbols from = a Go package like there is in JavaScript. I have programmed in both Go = and JS, and I have not found a real benefit to having to reference = everything explicitly in the import =E2=80=94 since you have to mention = the package name everywhere you use any package symbol =E2=80=94 but I = have noticed a benefit to not having nearly as much boilerplate at the = top of the file for import when working with Go vs. working with = Javascript. And my GoLang IDE just manages imports for me whereas = WebStorm just calls out when I haven't imported function names in = Javascript.

I am sure there is = more I missed, but that should cover the highlights.

The takeaways that I think would be useful are PHP = modules are:

1. Imports
2. Import = aliases 
3. Module-level consts
4. Module-level = init() functions
5. Module-level vars with = initialization
6. Module-level functions
7. One = directory =3D=3D one module
8. No hierarchy for = modules
9. Single word module names in = lowercase.
10. Module sytax being = <module><operator><symbol>, e.g. = mymodule->MySymbol

Takeaways I wish the PHP community would = consider but doubt there is any chance:

1. Having modules be HTTP(S) GETtable with = `php get <module>`
2. Uppercase being public, lowercase = being private, and no need for protected
3. Test packages with = testing build into PHP e.g. `php test = ./...`

>> I'm not fond of this = either.
>
> There will need to be a = way to define the entrypoint php.  I think index.php is reasonable, = and if another entry point is desired it can be called out -> = "mypackage/myentry.php"

Why is an entry = point needed?  If there is a module metadata file as I am proposing = PHP can get all the information it needs from that file. Maybe that is = the `.phm` file?

Maybe. Again, I need to look over this = meta data format. Also, how does it get = created?
=

As I am = envisioning, PHP at the command line would have the ability to = pre-compile a module =E2=80=94 aka all files in the module directory =E2=80= =94 and then write a module-specific file, maybe `.php.module`? That = could ideally be optimized for loading by PHP and have everything it = needs to know to run the code in that module.

That file could be completely self-contained = include all source code similar to a `.phar` file, or it could just have = a complete symbol table and still require the PHP source code to exist = as well. I have not pondered all the pros and cons of these alternatives = yet.

Clearly though even if it = compiled to a self-contained file the .PHP files would still be needed = during development.  Thus I envision that the PHP CLI would need a = `--watch` option to watch directories and recompile the `.php.module` = file upon PHP file change.  IDEs like PhpStorm could run `php = --watch` for users and non-IDE users could run it = themselves.

When PHP would come = across an `import` statement pointing to a module directory it would = first look for the compiled `.php.module` file and if found use it but = if not found it would recreate it. Maybe it could write to disk, or = generate an error if it cannot write to disk. OTOH writing to disk might = be a security issue in which case it could issue a warning that the = `.php.module` file does not exists and then compile the module to memory = and continue on.

It would be nice if = there was a mode where PHP would check the timestamps of all PHP files = in the module directory and if the compiled `.php.module` was earlier = than any of the .php file then recompile but you'd want that off for = production. That could be a new function `set_dev_mode(boolean)` or a = CLI option to create a `.phpdev.module` instead of a = `.php.module`.

Clearly anyone using = deployments could have their build generate all the required = `.php.module` files for deployment, and hosting companies that host apps = that don't use deployments like WordPress could have processes that = build the `.php.module` files for their users.

I think I have thought through this enough to = identify there are no technical blockers, but I could certainly have = missed something so please call it out if anyone can identify something = that would keep this from working and/or significantly change the nature = of PHP development.

BTW, this = pre-compiling would ONLY apply to modules, so people not using modules = would not have to be concerned about any of this at all.

-Mike

P.S. 
I remember when the choice to use = \ was made.  I've rarely been so angry about a language design = choice before or since.  I've gotten used to it, but seeing \\ all = over the place in strings is still.. = yuck.

Ditto.

= --Apple-Mail=_74499F48-6305-450A-92BF-A79571A79B6A--