On Sat, Oct 31, 2020, at 5:06 AM, Rowan Tommins wrote:

> > This would be an artificial limitation on attributes to patch
> > over the inherent inconsistency of the grouped syntax for nested
> > attributes.
>
> There is no artificial limitation; there is a binary choice: does
> #[Foo] represent an object or a list with one item in? This is
> completely new syntax, so there is nothing for it to be inconsistent
> with other than itself.

It is very much an artificial limitation. Developers would be prevented
from declaring that an attribute must be passed a single attribute 
with a particular type as one of its parameters. This isn't a natural
or inherent limitation of attributes, but an artificial one in order
to try to make the `#[Attr1, Attr2]` grouped syntax usable with nested
attributes.

> I am arguing that having it represent a list with one item in is
> actually *more* consistent, because when you attach attributes to a
> declaration, they are always retrieved as a list.

That's not necessarily the case for nested attributes. A developer
may want to declare that an attribute constructor takes a single
attribute with a particular type as one of its arguments. Why should
PHP prevent this by only allowing a (possibly empty) list to be
passed? Again, this would be an artificial limitation that reduces
the flexibility and usefulness of nested attributes.

On Sat, Oct 31, 2020 at 7:38 PM Larry Garfield <la...@garfieldtech.com> wrote:

> Perhaps a naive question, but I'm missing the downside of:
> 
>     #[Foo(Bar(name="baz"))]
> 
>     #[Attribute]
>     class Foo {
>       public function construct(public Bar $bar) {}
>     }
> 
>     class Bar {
>       public function construct(public string $name) {}
>     }
> 
> Why is that not OK?  Someone mentioned it means you couldn't call a
> function there, but... that's not a huge problem because I can't
> imagine why you would.  If we really wanted to avoid that:
> 
>     #[Foo(new Bar(name="baz"))]
>
> That would be unambiguous, if a bit ugly.

As I mentioned in my first email in this thread, there was an attempt
to do this back when the original `<<>>` attribute syntax was being
implemented. But this approach ran into difficulties since it would
require significant changes to constant expressions.

Even if someone finds a reasonable way to make such a syntax *work*,
it still has the downside of requiring a different syntax for top-
level and nested attributes (docblock annotations allow using the
same syntax for both). Moreover, re-purposing the syntax for function
calls or class instantiation is likely to cause confusion, since it
looks like the code is doing something other than what it actually
does (and of course it would prevent ever extending constant
expressions to support function calls or class instantiation).

One of my main motivations for proposing the `@@` shorter attribute
syntax was to avoid the complexity of grouped declarations and allow
using a single consistent syntax for both top level and nested
attributes. I fear that the change to the `#[]` syntax with grouping
will prevent PHP from getting a flexible and intuitive nested
attribute implementation, and devs will be forced to stick with
docblock annotations for these use cases.

Kind regards,  
Theodore

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

Reply via email to