Re: Previous discussions about generics syntax only?
| From: | Larry Garfield | Date: | Wed, 18 Oct 2023 16:57:10 +0000 |
| Subject: | Re: Previous discussions about generics syntax only? | ||
| References: | 1 2 3 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-121409@lists.php.net to get a copy of this message | ||
On Wed, Oct 18, 2023, at 11:01 AM, Alex Wells wrote:
> On Tue, Oct 17, 2023 at 10:40 PM Rowan Tommins <rowan.collins@gmail.com>
> wrote:
>
> Using the same syntax for type information that is guaranteed to be true
>> (existing run-time checks) and type information that is "advisory only"
>> (new checks for optional static analysis) means users can no longer have
>> confidence in that type information.
>
>
> If "syntax only" solution was temporary then warning users through some
> kind of opt-in mechanism (like with strict_types=1) may be enough - that
> way users will know that generics type information is "advisory only" and
> that this might change in the future. In some other languages (Kotlin)
> there are opt-in mechanism for experimental features - ones that are
> possibly incomplete, unstable or non-final, and it's working quite well for
> them.
>
> On the other hand, I can see a "third way": if the problem with current
>> static analysis conventions is that they have to be parsed out of a
>> string-based docblock, we can provide *dedicated* syntax, without
>> unifying it with the standard type syntax. For instance, some of the
>> earlier discussions around introducing attributes suggested reflection
>> expose the AST of the attributes arguments, rather than the resolved
>> expressions, allowing them to act a bit like Rust's "hygienic macros".
>> If that was added as an optional mode, you might be able to do something
>> like this:
>>
>
> The community has just now decided on the PHPDoc syntax for generics, has
> just started widely adopting them in packages and has just got first-party
> support from PHPStorm. I doubt that migrating to yet another temporary
> solution (one that still doesn't address all of the concerns) is a good
> idea right now.
That's fine for systems already invested in building and maintaining a docblock parser. But
that's a not-small lift.
In contrast, I built a serialization library that relies heavily on attributes. Most are opt-in,
but for array properties, you really have to use one of #[SequenceField(Type::class)] or
#[DictionaryField(Type::class, keyType: KeyType::String] so the system knows if it's a sequence
or dictionary, and what the types are. It just can't do most things without that knowledge.
I didn't want to add custom, proprietary attributes for that, but it was better than either
writing a docblock parser myself or adding and figuring out how to use a 3rd party dependency. I am
not happy with this solution.
If there was some universally recognized #[Array(Type::int)] (for a list of ints) or
#[Array(Type::string, Foo::class)] (for a string-keyed dict of Foo objects), I could easily access
through the reflection/attribute API instead. That would make life a lot easier for both me and
anyone using my library, as they wouldn't need to specify that information twice in two
different forms. It would still not be a "real syntax", but it would make the de facto
convention more accessible to projects other than PHPStan and Psalm.
That said, I agree that such an attribute-based convention, while it would be superior to the
docblock approach in almost every way, would still not belong in the language itself. Save the
language itself for if/when we figure out for-reals generics. That would be a project for PHPStan,
Psalm, and PHPStorm to collaborate on in user-space. (FIG would be happy to host such a discussion
if they were interested, but I don't know if they're at all interested.)
--Larry Garfield