All,

> An interesting point was brought up related to block mode:
> https://twitter.com/drrotmos/status/568540722586107904
>
> Namely that generated file caches may need the ability to switch block
> mode on-and-off.
>
> I'm considering making the change to add that. If that happens,
> declare must be the outermost block, and no non-declare blocks would
> be allowed in the outermost scope of the file:
>
> <?php
> declare(strict_types=1) {
>     //...
> }
> declare(strict_types=0) {
>     //...
> }
>
> Having trailing code or code outside of the declare would be a compile error.
>
> <?php
> declare(strict_types=1) {
>     //...
> }
> foo(); // compile error
>
> This behaves consistent with namespace block-mode today (though the
> strict type declaration would be required to be outside the namespace
> block).
>
> I'm considering adding it, as it's a valid use-case. What do you think?

So, I ran into a snag while doing this.

It turns out that in the parser implementation of declare is not going
to allow it without significant restructuring (including a lot of
validation in the compiler):

declare_statement:
statement { $$ = $1; }
| ':' inner_statement_list T_ENDDECLARE ';' { $$ = $2; }
;

So in block mode, declare supports inline, block and named-block mode:

declare(...) foo();
declare(...) {
    foo();
}
declare(...):
    foo();
enddeclare;

The problem with this is that namespace declarations can only happen
in top_statement (along with some other statements).

That leaves two options to support multiple modes per file:

1. Allow in top-level only:

declare(strict_types=1);
namespace Foo {
}
declare(strict_types=0);
namespace Bar {
}

2. inside of the namespace:
namespace Foo {
    declare(strict_types=1);
}
namespace Bar {
}

The problem with the first is clarity (it's easy to miss a declare and
not understand that the mode has changed). We pinned declare to the
top of the file for clarity. I'm not sure this use-case is worth
breaking that clarity.

The problem with the second is more subtle. With the current
parser+compiler, that declare would affect the entire file. It would
take pretty significant changes and restructuring of the parser to
effect.

We could drop declare() all together and go with something like a
namespace modifier:

strict namespace Foo {
}
namespace Bar {
}

But I don't think it's worth it to conflate those two together. Though
if we did, the syntax "strict namespace;" would be supported for
non-namespaced strict code.

So in the end, my conclusion is that while it would be nice to support
the "compiled file" use-case fully, it's not worth it from a technical
level (the risk and degree of change required doesn't offset the
benefit of it).

So the proposal will remain unchainged and not support the block
syntax (or changing the mode mid-file).

Thanks

Anthony

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

Reply via email to