Hi Rowan,

wt., 13 sie 2019 o 22:26 Rowan Collins <rowan.coll...@gmail.com> napisał(a):

> On 13/08/2019 18:45, Mark Randall wrote:
> > I thought about this as my first consideration, however it effectively
> > requires that the PHP code within the package class is fully parsed
> > and executed in order for it to retrieve the data.
> >
> > Consider pre-loading where the code is compiled, but not run, it would
> > not be possible to use namespace level defines to add compile-level
> > optimizations or checks (at least without some AST hackery).
>
>
> Ah, that makes sense. Does that necessarily mean we need a dummy class,
> though? The autoloading logic in the engine knows that it called the
> autoload callback expecting a package definition, so can count as
> success that the package is now defined.
>
> In other words, the file the autoloader included would look like this
> (again, sticking to the notion that "package" is separate from
> "namespace"):
>
>
> #
> # File: /lib/company/project1.php
> #
>
> <?php
>
> packagedef company/project1 {
>      strict_types=1;
>      strict_operators=1;
>      upgrade_errors_to_exceptions=E_ALL;
> }
>

Was thinking a while about proper syntax and would like to mention what I
said before.
It doesn't have to be a new syntax if we agree to put package definiction
in sort of separate configuration file.
In the end all what we need is package name and a bunch of declare
directives.
Given that it could be easily done using separate conf file like:

# package.ini
[package]
name = MyVendor\MyLibrary
strict_types = 1
encoding = UTF-8

# package.json
{
  "name": "MyVendor\\MyLibrary",
  "declare": {
    "strict_types": 1,
    "encoding": "UTF-8"
  }
}

# package.toml
[[package]]
name = "MyVendor\\MyLibrary"
strict_types = 1
encoding = "UTF-8"

# package.yaml
name: MyVendor\MyLibrary
strict_types: 1
encoding: UTF-8

That way it would prevent to mix normal PHP code with package definition,
cause every possible PHP syntax
we would agree, opens the door to add something more to that file, for eg.:

# package.php
<?php
declare package MyVendor\MyLibrary {
  strict_types = 1,
  encoding = "UTF-8"
}
function foo() {}

In this early package design stage, all what we need and what was the
motivation of Nikita RFC[1] which was to
provide a solution for package/namespace scoped declare directives -
nothing more.

Thus with the configuration file, it would be easier to add more directives
and deprecate them / ignore additional settings.

I was thinking over the current state with valid directives, which now are:
strict_types, ticks and encoding.
Although I don't use ticks and encoding, both works in very narrow cases
and could be cleaned up.

* encoding - seems to work only if PHP was compiled with additional
configure flag mostly as I suspect
  in whole project/library/package rather than a single file;
* ticks - this is only for declaring the ticks=N - the number of ticks
which without register_tick_function[2]
  so the N argument probably could be even moved as a parameter while
registering tick function
  BTW: official examples show the second parameter as true but there is no
description on what does it affect

Going further IMO it would make sense only to adopt encoding as a proper
package declaration with strict_types directive.

I'd like to refer to the package name as part of FQCN.
If that would be a part of FQCN like for eg:
<?php
use MyVendor\MyLibrary:FooBar\Baz;

Then it would be possible to extract it and load package definition before
class autoload would attempt to load
source file and meet:

<?php
package MyVendor\MyLibrary;
namespace FooBar;
class Baz {}

In a future, a separate configuration file can be easily used for
preloading (by glob mask) or bootstrapping,
for eg. (no matter of agreed format):

# package.ini
[package]
name = MyVendor\MyLibrary
preload = src/**/*.php
bootstrap = src/functions.php

Or even defining editions, like:

# package.ini
[package]
name = MyVendor\MyLibrary
edition = 2020

Concluding I can see more benefits adopting separate configuration file
than drawbacks in oppose to PHP file:

Benefits:
* hard to write syntax error
* impossible to inject user code and avoid circular dependencies, when file
/lib/company/project1.php declares or uses
  other symbols from a different package which would require loading
machinery to load it and cycle own usage
* doesn't add PHP parser complexity
* easy to ignore abandoned attributes
* together with package name part of FQCN loaded before any package source
code parsing
  (well here is something missing when trying to directly execute a file
with package scoped class and it's usage)
* not possible to dynamically create the package definition
* good place to provide an edition (if ever such an approach would be
adopted) - which could be by design a set of strict
  declare directives without the need to specify each strict_* directive
separately

Drawbacks:
* need for new loading machinery
* not possible to dynamically create the package definition (this could be
an argument for and against depends on needs)

P.S. Maybe I'm repeating myself, then I'm sorry.
I just got an impression that wasn't heard enough.
Please comment your thoughts on that.

[1] https://wiki.php.net/rfc/namespace_scoped_declares#motivation_and_vision
[2] https://www.php.net/manual/en/function.register-tick-function.php
-- 
regards / pozdrawiam,
--
Michał Brzuchalski
about.me/brzuchal
brzuchalski.com

Reply via email to