On Sat, Jan 18, 2020 at 11:53 PM tyson andre <tysonandre...@hotmail.com> wrote:
> > I'd much rather have something like: > > > > declare(ambiguous_element_lookup=0) > > > > declare(ambiguous_element_lookup=off) > > Aside: declare(unambiguous_element_lookup=1) is probably a better choice > than my first choice of (disable_ambiguous_element_lookup=1), but probably > not the best choice. > > > I find that the “disable_ambiguous_element_lookup” directive name is, > well, ambiguous. > > Does it mean that it will look up only in the current namespace, or only > in the global namespace? I can’t guess. > > > > Maybe a three-value directive: > > > > declare(function_and_const_lookup=global); > > declare(function_and_const_lookup=namespace); > > declare(function_and_const_lookup=fallback); // the default > > That's my favorite setting name overall so far - it ends up being as long > as disable_ambiguous_element_lookup and more self-explanatory. > I don't plan to include namespace-only in the RFC - future RFCs could > propose additional values independently. > > Probably just `= global` and `= default`, because the default might > eventually change (from the fallback), > and = fallback could be added if the old fallback was desirable enough. > - `= default` would only be useful to set resolution back to the default > with future language changes such as > https://wiki.php.net/rfc/namespace_scoped_declares#implementation_considerations > It looks like the implementation has been updated to the style proposed here, while the RFC still uses disable_ambiguous_element_lookup. I like the idea of using a meaningful value here, but think that this should be using a string, i.e. declare(function_and_const_lookup='global') rather than declare(function_and_const_lookup=global). Currently declare() syntax uses a normal constant expression on the right hand side of the =, and I don't see a strong reason why we should deviate from that for this feature. An existing declare using a string is declare(encoding='UTF-8'). The RFC says: function sprintf($msg, ...$args) { // this and remaining statements still refer to \sprintf, not MyNS\sprintf return sprintf("Prefix $msg", ...$args); } This looks a bit peculiar... We could also say that declaring a symbol also automatically brings it into scope. I'm not really sure which is better. As a general note on the overall proposal: I think this is a very pragmatic proposal. It addresses a real issue, and it addresses it in the most straightforward way. You can just drop the declare in your code, and it will keep working exactly as it did before, just faster. Assuming you weren't doing anything stupid, of course. The big downside is that this makes class and function symbol resolution complete opposites. Classes only look in the current namespace. Functions only look in the global namespace. This reflects the way they are most commonly used, but is not a great place to end up from a language design perspective. There are two alternatives that keep class and function symbol resolution the same: One is to always only look in the namespace. This has been suggested a few times in the past, including in this thread, and the RFC https://wiki.php.net/rfc/fallback-to-root-scope-deprecation. I think this is a fairly unpopular option, because using fully qualified names for functions tends to be quite ugly (more so than for classes, due to the positions they're used in), or requires a large number of imports, as even a small piece of code can easily use a dozen different string/array functions. One option that I haven't seem much discussion on is the opposite: Always only look in the global namespace. Any unimported unqualified usages will be treated as fully qualified names. This would match the proposed semantics for functions/consts and change the resolution rules for classes. I think this would have relatively little impact on how code is written, as classes already tend to make extensive use of cross-namespace references and the import is usually IDE managed. Regards, Nikita