On Mon, Mar 9, 2020 at 11:03 PM Larry Garfield <la...@garfieldtech.com>
wrote:

> On Mon, Mar 9, 2020, at 9:42 AM, Benjamin Eberlei wrote:
> > Hi all,
> >
> > I want to resurrect Dmitrys Attributes RFC that was rejected for 7.1 in
> > 2016 with a few changes, incorporating feedback from the mailing list
> back
> > then and from talking to previous no voters.
> >
> > The RFC is at https://wiki.php.net/rfc/attributes_v2
> >
> > A working patch is at https://github.com/beberlei/php-src/pull/2 though
> > work around the details is still necessary.
> >
> > The RFC contains a section with common criticism and objections to
> > attributes, and I hope to have collected and responded to a good amount
> > already from previous discussions.
> >
> > There is also a fair amount of implementation detail still up for debate,
> > which is noted in "Open Issues". I have pre-committed to one approach,
> but
> > listed alternatives there. On these issues I am looking for your
> feedback.
> >
> > greetings
> > Benjamin
>
> I am very excited to see this back, and overall I like the approach!
>
> Thoughts in no special order:
>
> * It's not entirely clear, but the values in an argument-carrying
> attribute are passed to its constructor variadically?  Viz:
>
> <<Foo(1, 2, 3)>>
> function stuff() {}
>
> class Foo implements Attribute {
>   public function __construct(int $first, int $second, int $third) { ... }
> }
>
> Yes?  (And then if you wanted to capture them all you could use a ...$args
> parameter in the constructor.)
>
> * It looks like the only way to support named parameters would be to pass
> an associative array and decompose it yourself.  That's... better than
> nothing I guess but also we're back to the same lack of self-documentation
> we always lament.  Is there any opportunity to do named parameters in some
> other way?
>

Improvements here are contingent on any named parameters support, which
could

>
> * Is it possible to inline a sub-object, or no?  Viz, is this legal, or
> would we want it to be legal (I'm assuming it's not at the moment):
>
> <<Foo('a', 'b', Bar('baz'))>>
> function stuff() {}
>

No thats not possible, because the constant expression syntax doesn't allow
this. See Tysons proposal lately to allow function calls in constant
expressions: https://externals.io/message/108630

>
> * I *really* dig how you can filter annotations to just those that match a
> certain parent class/interface.  That was one of the nicer parts of PSR-14
> so I'm really glad to see the same "make the type system earn its keep"
> approach here.  It encourages packages to interface-tag their annotations
> so they can easily grab "just theirs".  +1
>
> * The "more complex Doctrine ORM use-case" example includes inlining
> multiple annotations together: <<ORM\Id, ORM\Column, ORM\GeneratedValue>>
> .  Is that just an oops since that possibility was only just added to the
> Open Issues?
>
> Ah this is a mistake, I removed that use-case and settled on a single
syntax.

>
> Regarding open issues:
>
> * If constant expressions are easy enough to support, I don't see a reason
> not to support them.
>
> * I'm torn on the marker interface.  On the one hand, a marker interface
> would make it easier to audit a package for all of its attributes; just
> grep for "implements Attribute".  I'm sad that we didn't get a marker
> interface in PSR-14 for that reason.  On the other, if it doesn't do
> anything except be a marker then it doesn't really offer anything else; and
> it also potentially makes it harder to add some special casing of
> attributes in the future, say to offer "if you want this extra attribute
> behavior, use this interface/base class/whatever."  I could go either way
> here.
>
> * Letting attributes say where they're legal would be a good case for such
> a more-than-marker interface.
>

I am not sure. This is something PHP would validate at
Reflection::getAttribute() time, at which time it is also easy to validate
for userland implementations.

>
> * The aforementioned example of specifying where an attribute is legal
> implies that attribute classes can themselves have attributes.  True?  If
> so, that should be made explicit elsewhere in the RFC.  I'm not against
> attribute-ception, but that should be explicit.
>
> Attributes are just PHP classes, so they can indeed have their own
attributes. So a userland library building on top of attributes, could call
getAttributes() then validate that each attribute returned has itself an
attribute that "marks the target":

<<Target(["class"])>>
class Entity
{
}


> I think my only significant pushback at the moment is that attributes here
> suffer from the same redundancy problem as any other value object.  To wit:
>
> class Owner implements Attribute {
>
>   public readonly string $name;
>
>   public readonly string $title;
>
>   public readonly int $age;
>
>   public function __construct(string $name, string $title, int $age) {
>     $this->name = $name;
>     $this->title = $title;
>     $this->age = $age;
>   }
> }
>
> <<Owner('Larry', 'Manager', 99)>>
> function stuff() {}
>
> That necessitates the same quadrupal-repetition that other constructors
> have.  Since I anticipate the 99% use case to be exactly that, the pain of
> that redundancy (and the mandatory unnamed order) will be felt rather
> dramatically here and thus hurts ergonomics.  Is there no way that we
> address that?
>

This is not something to fix for this RFC, but any solution here and
attributes can benefit from it as they are just PHP classes.

>
> I realize the answer may be "no more than any other class, they all suck
> equally".  Are we at least certain then that if we can solve that in the
> future for classes generally that it will automatically work here?  (Eg, if
> new Owner({name: 'Larry', 'age' => 99, 'title' => 'Manager'}); became a
> legal shorthand for the above, it would automatically work for annotations
> as well.)
>
> Overall nice work, and I hope to get to use it.
>
>
> --Larry Garfield
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
>
>

Reply via email to