Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:109692 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 62575 invoked from network); 16 Apr 2020 19:52:14 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 16 Apr 2020 19:52:14 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id BCE0E180510 for ; Thu, 16 Apr 2020 11:22:25 -0700 (PDT) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,HTML_MESSAGE,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2, SPF_HELO_NONE,SPF_NONE autolearn=no autolearn_force=no version=3.4.2 X-Spam-ASN: AS15169 209.85.128.0/17 X-Spam-Virus: No X-Envelope-From: Received: from mail-wr1-f46.google.com (mail-wr1-f46.google.com [209.85.221.46]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Thu, 16 Apr 2020 11:22:24 -0700 (PDT) Received: by mail-wr1-f46.google.com with SMTP id x18so6037229wrq.2 for ; Thu, 16 Apr 2020 11:22:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=beberlei-de.20150623.gappssmtp.com; s=20150623; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=b6VSS0EhXBHcuCVKUOXhqm3PcYF2p+Dq6Z3TogR6Fqw=; b=hkcIZ5432WbfMScVS3Zxx/wcvH3CH/fYIi+GR0d+1V+1FBMB6LMU4ohb4yF/JhPv2q MppKGb5XrZnp4Nopt0d6GSc6Wazcc/vKwB7peHu8DXt62MHov7WvlXCtnaHUyom9vTPe CdoqJfVi/gjfeh9yXzK/8NctPsDGpKKQngGlJig67lE10FlHTKR42F7QkU0XltwZTTOc fFDB3CwFUsEhCjttK96s5RrBIKHXYEmaxS440oSEA4xtYG9TmZXNp/yCsFK643rtvyb6 reXOslt/a2TKX9jArINsrTGbhixDZQX2praGf0SlKoWKs1MCnVo0ciEbzgKi7J+vOkwM SXHw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=b6VSS0EhXBHcuCVKUOXhqm3PcYF2p+Dq6Z3TogR6Fqw=; b=PqsoouOlX+4kzdhNvg5pZpWyphyKFq+f5IrbSddGtZSztP82lDsiHDYWpEENUkRwm+ ejm4TAXGNYYNdsnh5+xcMKbDhylDE+MX3IbdIWinbLqqE+SoTE+KUrYWl8/uNf2WjJ5L ry4snR41oByVOhkk5vq1rl52gAUpH451VLCbJDookAm+Z5nRTyVprC3x7cU8nikcLa/5 elymfQr29tOMUcMIv8XTnlPyebOk3IDO5eXoYyBfJcCImw2LiWNuqMseYwKQdzW+OSKd ck7d2g2T53oBV6INRU6DZp2xdA3zuunf/yehuKI5LnCqf4lfSup3H0tBuP456WyK5K7G m2kQ== X-Gm-Message-State: AGi0PuYGqdAeOFrUyqHV54g215KShiXtf2o7ba7uOG1kjhpGQJvL1lm5 0dHJibc/Ir/bD35qLhpCk+HK81KIHnwJLTJ6JgHyjw== X-Google-Smtp-Source: APiQypIc3pc1ll6Vsvy7eZhatNq3V18QvNLrDnZ5ttcEgODBIg6Mi4+5DtCf/3n/MegwjR/OONWuqsYz+zWqH4a/LGk= X-Received: by 2002:a5d:4b90:: with SMTP id b16mr26891435wrt.16.1587061343281; Thu, 16 Apr 2020 11:22:23 -0700 (PDT) MIME-Version: 1.0 References: <16620f3a-1eb6-437e-aa6f-05e5be2aa713@www.fastmail.com> <231390ee-ff9c-4f7b-918a-4f87a676613e@www.fastmail.com> <11f35e10-5bee-4b28-b784-69f7f5f2f11e@www.fastmail.com> In-Reply-To: Date: Thu, 16 Apr 2020 20:22:12 +0200 Message-ID: To: Nicolas Grekas Cc: Larry Garfield , php internals Content-Type: multipart/alternative; boundary="0000000000009a754005a36c8391" Subject: Re: [PHP-DEV] Re: [RFC] Attributes v2 From: kontakt@beberlei.de (Benjamin Eberlei) --0000000000009a754005a36c8391 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Thu, Apr 16, 2020 at 4:41 PM Nicolas Grekas wrote: > Le jeu. 16 avr. 2020 =C3=A0 16:29, Larry Garfield a > =C3=A9crit : > >> On Thu, Apr 16, 2020, at 1:46 AM, Benjamin Eberlei wrote: >> >> > > > > 3. I see the most common case for attributes being getting the >> object >> > > > > version. With the reflection API as currently described, I see >> two >> > > > > shortcomings. >> > > > > >> > > > > A) I can't tell if an attribute has a valid object or not before >> > > trying to >> > > > > access it, which would presumably fail spectacularly. I believe >> we >> > > need a >> > > > > way to know if getObject() is going to return a valid value befo= re >> > > trying >> > > > > to call it. I think this is a hard-requirement. >> > > > > >> > > > > B) Related, as is getting all attributes as objects looks to be >> rather >> > > > > clunky. >> > > > > >> > > > > $attribute_objectgs =3D >> > > array_filter(array_map(function(ReflectionAttribute >> > > > > $r) { >> > > > > if ($r->getObject()) { // Needs something better here. >> > > > > return $r->getObject(); >> > > > > } >> > > > > }, $obj->getAttributes())); >> > > > > >> > > > > That's gross. :-) Can "get all the attributes that can be forme= d >> into >> > > > > objects" be its own operation? $obj->getAttributeObjects() or >> some >> > > such, >> > > > > that skips over non-instantiable attributes and instantiates the >> rest? >> > > > > >> > > > >> > > > I don't see A.) what would you do when the object instantiation >> fails? >> > > You >> > > > would throw an exception I presume, let the engine throw the regul= ar >> > > > TypeError, ArgumentError, Error if class not exists that everyone = is >> > > > already familiar with. >> > > > >> > > > For B.) I believe you are extrapolating based on your own use case= . >> > > Working >> > > > with Reflection is usually a lot of boilerplate, I don't believe w= e >> need >> > > to >> > > > have a one liner here. >> > > >> > > It depends on the annotation, I suppose. If I'm requesting a specif= ic >> > > annotation by name, presumably I know if it is supposed to have an >> > > associated class. If it's supposed to but it's missing, that's a >> legit >> > > class-not-found exception/error. >> > > >> > > However, I'm thinking of cases where code is integrating with a 3rd >> party >> > > optionally, through an annotation. In that case it's a fair questio= n >> of >> > > whether the class will be defined or not based on whether some other >> > > library is present. >> > > >> > > Similarly, if a bit of code is requesting all attributes (as above) >> rather >> > > than just specific ones by name, it wouldn't know if a given >> attribute is >> > > supposed to be defined or not; as written, class-less attributes are >> > > supported. >> > > >> > > I suppose the workaround would be class_exists($r->getName()). Weir= d >> but >> > > I guess works? It would have to be documented as a thing you should >> do, >> > > though, which implies to me that it could be made cleaner. >> > > >> > > That reflection is usually clunky today (true) is to me not a >> compelling >> > > argument that it shouldn't be made less clunky. :-) >> > > >> > >> > You are not safe from these problems when using Doctrine Annotations >> either >> > (missing library or class does not exist) and it fails exactly the sam= e >> way >> > as trying to instantiate something that doesn't exist. >> > >> > I also realized why IS_INSTANCEOF is not the default, because it needs >> to >> > resolve all attributes to classes to perform the check. This triggers >> > autoloading *all* attributes of the reflected declaration (even the on= es >> > not requested), so we felt it should not be the default. >> >> Ah, valid. I suppose that's an unavoidable result of allowing >> non-class-mapped attributes, which means anyone building on it is stuck >> doing their own class_exists() check for everything. >> >> Sad panda. (Still very +1 on the RFC, just sad panda about these >> details.) >> > > > Same here, sad panda: > - we're going to miss nested structure instantly - I wish we could try > harder here. I'm actually wondering if using the syntax for object litera= ls > would be the solution here? (we don't have any yet, but some proposals ha= ve > been mentioned recently. > Nested attributes are intentionally not part of this RFC, because I believe it is better to attempt to integrate it with as many existing concepts as possible, with the potential to benefit from future additions (named function params, constant AST/expression improvements). Inventing a completely new syntax will cause future problems for the language, and the extensibility of attributes themselves. I can't guarantee you a timeframe for any of that, as mentioned before, I see it much like scalar types missing nullable in PHP 7. Nikita mentioned potential improvements to constant AST in a reply to his ctor promotion RFC, Tyson also discussed it a few weeks ago, and I plan to look into this myself if this RFC is accepted. And then there is also the potential of the named params RFC being revived as discussed a few days ago. Your mention of object literal syntax is a very good example why nested is not in this RFC. if we invent our own nested attributes syntax now, deviating from PHPs expressions, we might never be able to integrate general expression improvements into attributes and be left with two syntaxes that can't benefit from each other. In addition we will be left to maintaining both. Hypothetically, if we had named params and object initializer in PHP (which makes no sense, because they somewhat do the same thing), plus the ability to evaluate more expressions, then the following would automatically be possible in an attribute: < "users", joinColumns =3D> [new ORM\JoinColumn{ na= me =3D "id, referencedColumnName =3D "user_id" }])>> Then ReflectionAttribute::getArguments() returns: ["name" =3D> "users", "joinColumns" =3D> [object(ORM\JoinColumn) { "name" =3D> "id, "referencedColumnName" =3D> "user_id" }]]. Hope this clarifies a bit on the RFCs approach. > - having declarative statements possibly turn into failures is also > unfortunate. This makes me wonder if the attributes shouldn't be turned > into plain arrays instead? The logic to hydrate objects would then be mov= ed > to some userland libs. Would that make sense? (I know, that conflicts wit= h > my previous proposal, I'm just trying to explore :)) > The attributes can be turned into arrays as well, see the ReflectionAttribute object in the RFC getName and getArguments functions. Only ReflectionAttribute::getAsObject can turn into a failure. This is the reason Reflection*::getAttribute does not immediately convert to objects. This gives the most flexibility to userland, but also establishes the convention how attributes are "mapped" to objects. > > Nicolas > --0000000000009a754005a36c8391--