Hi!

> If we want to evolve the language without breaking backwards compatibility,
> we need to provide a way for gradual migration of the ecosystem: A library
> should be able to opt-in to breaking changes, while remaining usable by
> downstream consumers. Conversely, an application should be able to opt-in
> to breaking changes, while still being able to use an older library.

This assumes breaking changes are necessary for evolution. I am not sure
this is actually true. Java is 21 years old, and I think the code I
first wrote when I learned Java in late 90s would still compile today
(even though nobody would probably want to run it :).
Javascript is 23 years old, and the only thing I can think of that may
break BC is "use strict", which is also local and just one option.
C++ had a myriad of changes lately, and is 34 years old, but I am pretty
sure code written a decade ago - discounting library changes, etc. -
would still compile today.
I think the assumption that we *must* break old code to be able to
evolve is not correct. Surely, certain directions of evolution - like
converting PHP to strictly-typed language - would require that, but
that's not the only direction possible.

> 3. Support per-directory declares, which is the direction I was planning to
> explore next. This is based on the premise that all library files are part
> of some top-level directory, which I think is a fairly safe premise (note
> that the "directory" could also be a phar file).
> 
> The actual intended use (similar to the namespace-based variant) is that
> people will specify their declares in the composer.json file, and composer
> then includes a call to declare_directory() or similar as part of the
> autoloader. Projects not using composer have the choice of issuing an
> explicit call.

Note this also means that syntax and semantics for each file is
runtime-defined and can change any time. With obvious implications for
preloading and opcode caching. Moreover, there could be a situation
where some code includes a file with one set of options, and then
declare_directory() happens that changes the options and another code
includes the same code assuming different set of options. I have no idea
what is supposed to happen in this situation. Since declare_directory()
is non-local, I see no way to ensure that require for certain file
always happens with the same set of options. Of course, one can say
"composer and autoloading will ensure that" - but composer and its
autoloading, while undoubtedly popular, are libraries external to PHP,
and there's a lot of PHP code that is either not using composer, or
using composer in combination with other ways of autoloading. Unless we
mandate use of composer for every PHP project, this still does not solve
the issue.
And, of course, IDEs/analyzers would somehow have to figure this out too
- since composer.json is not actually defining the options (it is only
an input for declare_directory call sometime later) they'd probably have
to parse code and find declare_directory() calls? Or they'd just assume
everything in composer.json? What if I just manually call
declare_directory() then - would it break everything?

> 4. Specify declares in a special file, similar to how INI directives are
> declared. The suggestion here has been that PHP could scan the path of an
> included file upwards to find a declares.json (or similar).

This one at least ensures options for certain file are consistent, but
at the cost of introducing magic config files that PHP never had before,
and all complications coming with handling, caching and managing those
files (if declares.json changed, do you have to invalidate all opcode
caches for all files under this directory?).

> 5. Introduce a first-class module/package concept and support per-package
> declares. This is arguably the closest fit for what is needed, but also the
> most complex solution. This is a fairly big problem space and I personally
> do not want to pursue this outside a certain narrow scope.

That actually would be a workable solution if package semantics were
built into the language. That would ensure same code is always
associated with same options, allow compile-time handling of options and
would let IDEs, analyzers, etc. to have a consistent picture without
trying to parse runtime code. If I had to choose among the options here,
so far it's my favorite one, even though I recognize it may not be easy.

-- 
Stas Malyshev
smalys...@gmail.com

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to