Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:92708 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 91183 invoked from network); 25 Apr 2016 07:42:58 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 25 Apr 2016 07:42:58 -0000 Authentication-Results: pb1.pair.com smtp.mail=dmitry@zend.com; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=dmitry@zend.com; sender-id=pass Received-SPF: pass (pb1.pair.com: domain zend.com designates 157.56.110.119 as permitted sender) X-PHP-List-Original-Sender: dmitry@zend.com X-Host-Fingerprint: 157.56.110.119 mail-bn1on0119.outbound.protection.outlook.com Received: from [157.56.110.119] ([157.56.110.119:50313] helo=na01-bn1-obe.outbound.protection.outlook.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 56/C0-17738-E7ACD175 for ; Mon, 25 Apr 2016 03:42:56 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=RWSoftware.onmicrosoft.com; s=selector1-zend-com; h=From:To:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=quHG8vh+nt8C45oMcLyKt4v4qHPT6K+aMEfqhMa/e5Q=; b=6PnoXsznCl2BoigSx4wdWJvBhoKTMGtVcY68iD12vOBqjGzfspFVaX36qfRvjxY+Mf3Iv+/H+gAjugP1qpGnuZdnjFRjI3k3Ct9saJKidlQUVT2rJfphLpL6HhnIr+Rhpvd1CfKOicuBRV0HVfT9fbV+9hezbUUKjvvWJuIVoAE= Authentication-Results: lists.php.net; dkim=none (message not signed) header.d=none;lists.php.net; dmarc=none action=none header.from=zend.com; Received: from tpl2.home (92.62.57.172) by SN1PR0201MB1791.namprd02.prod.outlook.com (10.162.228.21) with Microsoft SMTP Server (TLS) id 15.1.466.19; Mon, 25 Apr 2016 07:42:48 +0000 To: "guilhermeblanco@gmail.com" References: <571965D1.9020102@zend.com> <5719CDB2.90103@zend.com> CC: Dominic Grostate , PHP internals Message-ID: <571DCA6A.2070803@zend.com> Date: Mon, 25 Apr 2016 10:42:34 +0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.7.1 MIME-Version: 1.0 In-Reply-To: Content-Type: multipart/alternative; boundary="------------050808030000050405020508" X-Originating-IP: [92.62.57.172] X-ClientProxiedBy: VI1PR07CA0105.eurprd07.prod.outlook.com (10.165.229.159) To SN1PR0201MB1791.namprd02.prod.outlook.com (10.162.228.21) X-MS-Office365-Filtering-Correlation-Id: 0d5dcb78-b97c-4b1f-eef4-08d36cdd339d X-Microsoft-Exchange-Diagnostics: 1;SN1PR0201MB1791;2:OagUvJZiYvLcsakI8Nmqish/6o3D1ZQaclXH23wHsOO/5YKAbG7xoxtsgBVLsmmikQvEyVTTEmQV9km8G3X17ek3rV22oOn5cytNUQnqtcZ4lKll2NXlZynwo3KdKEgH9rNJKYmpw+xhxMSTkJ/a76MjGYh4ZVEAWl7eyYafgnMNiyeXGMRqj3i95s74of/B;3:OkPtHl4E9tQUmLk2mvvCa+tsQXzY1Z4fHgaWXobjYU5iSovsDYmZ0w6NkA61P4uc2aZo0dbtSXBXk0JqAyWyw4M37KBG87CU7FJ89VsklNthiLbrs0EnhZ2gpJBSbKGZ;25:D6ph9LpTnjetFn4GD9TksKYCskXpPkPBTjQUJFIGWvFTVgHLEQB6ZXZR8sKiCCrXxDZLpzD8YNOnZ1cWnTLVVgnzMy3HmfekQZ5UDPycZb58b8lIxr3JeSQdSA4ZsW0H6ppL8BVQezaNfN2q+8fblrvqTP4l6mmlBUPK7w0wgEFIob5cdC39C1iRf1hyjLul0JKOt+dLtPau9nErnEuuocuZS392ptDhsrFXN/RfJlzzGVFNSP/A2jX6JiX93Giu8l/W2s4gGve2zLanPt/HCEf3EH33umnGFl92xxYSf7E3Envd09gOj6AgG3tzyg+vUAHwGMiAVvIHLm3TZz7qkw== X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:SN1PR0201MB1791; X-Microsoft-Exchange-Diagnostics: 1;SN1PR0201MB1791;20:pcveg3bJbT3xjYPGYspEDRdhGtx8EBRx6hGWKH1q8DHYJXy6IyXojuoFTEu3C6kxG1lDYWHs4D0VMVqb/db7Tlb4XRJLz/Q/sVdL9ZO88Fp0DIhSJt0vBQV7g/3vpsFlB4bZNruFaWk5Q8g58ipt0xtA4W7I9QUBo60DPBq1oRops1IsR5Nu0Ce88Np6g8AkoWe1BkolbJnHMi+opx9Gks0zPa82WP/ZO3bAwkO0CADMcC3W5yYCU8XpsXmCfzZrpX/hPQ1K2eLLR4YdMOMwxkntRJaf0iciDo5iRd022vFIG1QBO7N1nepz8JlrtiyjaxXzU61PnGkeG1VVkG3/shpDH4kA9hViub+em2m2/qBWbZA+L+5I7zwCwTPMeBSE01aaPYobb2uWJeCRYZjQyI95z/4odPlio2w9zwH+/tYL1ctlx6TvULuipHh+9I4vfjWrcH5vjYFmIZZJnwuMpASbqPZR23kGKjnON8dyXXuEVXTqnNLWIEKyFSeE8cWx;4:OqipagzjfZ6SKABHEoMUA+M1j7P57/ejt0f6jK7y5nPjCSqxsbPT3YeDhPPRmxob1GN1ceZ48j7oq/K3gCoJLVZTpmSaHIXMmZdcKYDjR8wrETdQHf4zrz62x++rIbj5HsbPtLPgJ7QKLQgHV6haImFhDdrRryY7acGxadTobyoKLWiOgqN3+QUe05xExcXZHaDHM2e45O73uuYEwZW3eaFs1rEi+IzulcUk0YHISt9cbK+BPKxJEFiXPdBr5Y8e5aoSeIUHIq0MpkN06+cA7GQ458zQenrOtAUym1bjVk8iufVmM+JD2wOoNvadv+m938B5kluWAeWO0/qsyr6qfApsVLOU8dnSP1vh1I2gdpR5aTC1O1i0++Tvxmvij8UHN4RfgNFuQYQ716FxUoy2DA== X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(9101521062)(601004)(2401047)(8121501046)(5005006)(3002001)(10201501046);SRVR:SN1PR0201MB1791;BCL:0;PCL:0;RULEID:;SRVR:SN1PR0201MB1791; X-Forefront-PRVS: 0923977CCA X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10019020)(4630300001)(24454002)(377454003)(5008740100001)(92566002)(50986999)(110136002)(76176999)(5640700001)(54356999)(81166005)(65816999)(42186005)(87266999)(2501003)(83506001)(59896002)(2351001)(586003)(189998001)(512874002)(6116002)(3846002)(64126003)(2950100001)(1096002)(36756003)(561944003)(1411001)(33656002)(1730700002)(5004730100002)(19617315012)(16236675004)(4326007)(2906002)(77096005)(270700001)(86362001)(65956001)(84326002)(19580395003)(15975445007)(93886004)(66066001)(19580405001)(579004);DIR:OUT;SFP:1102;SCL:1;SRVR:SN1PR0201MB1791;H:tpl2.home;FPR:;SPF:None;MLV:sfv;LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;SN1PR0201MB1791;23:c/uKJhq4ydf/lntpi33e21q9UaDtyPC02NPfPIh?= =?us-ascii?Q?mBJf0zAsrwyWp5FjijQkHV0X7fKCN1+6fs52szbs3poIIZz/GVBbq+qdgGK2?= =?us-ascii?Q?pOqmYgI065ybHuzOkHKfNXALU1qTVWY26mAQoLyuikB7w1ldEHEctjoOV1tA?= =?us-ascii?Q?0BZMp8iWJJWiW2GPcnI9JFJ1Oie2k5UlOD8hF2WhA1KOF60/WesNaT9nEC4J?= =?us-ascii?Q?SWczZ3MTXEjVhIDDU0ciT4+qm6FF2YEMxKX/eq5gsx6Z7fOFVr2J0EdOJuXK?= =?us-ascii?Q?DgDeFDPI+0JdP1ElkNVyLsVUfcfjBGN1HjLN90hr/mooGDfyT7r9szXKrX8b?= =?us-ascii?Q?0PnEV7ZLYRZBsuUWEsK4A42MdzLRba7q43OPBBOcxMsBUM93TacAwVw7FoK5?= =?us-ascii?Q?hsoUODCUOuEvqNzXuJv5Sr80bw9wzO8WsOGiLOeeDXC9bVPKzght7bY+KZkR?= =?us-ascii?Q?V3VA//uqlIOmLx8Hr9Iu/vAiFpukSGh5cBzoIEqSi8wiaY+shjd6WqIAyiac?= =?us-ascii?Q?nYrUGSTNmbRtTcrqM+uh7M0YOUXZeik4Mq+AMCBEzANMQ0KVTgbXxwRSGSZG?= =?us-ascii?Q?t7fDAffFEMW2K6QqfeAchpTRC2I85/DAADpmIQE/k9BksDzJMJKhNFhTL6E5?= =?us-ascii?Q?VlL1SflDOSgSKrK5OtmJP85pTWFpAlvOH2cQSZcYzbj8a9LdQOrbURuZCM6/?= =?us-ascii?Q?S/lxFQijK0TFLKh8K4VaSE7Y0qOCJIHr/2QZeWR4LZ2ozoZEG7ys9xaOlaYG?= =?us-ascii?Q?Gtli0pAzGTZXBS8ox8Y3ey5DQ44wSnEn+A6HrDIx+wu2M2uTbG7qGkZsbXCf?= =?us-ascii?Q?2CjBKDxIabarkLZjEekFB6oq+eh/qWmFRtIc7s678XZGD6/BYNlMyqD3GKTn?= =?us-ascii?Q?bys7Z1ohcv2nV4PbeAqKPaxFBGCxKKjQHnfuERwTrGh8K427TksX5iy5Z2PG?= =?us-ascii?Q?GUKwY+j1LixnNwPvztH5EaH9nSc0OP2EnwEviPtFoI2o9DNsk0cLO4/D/1tx?= =?us-ascii?Q?2pwRRgJZsZOjFy3UqUo/rJMHtQXcP5L270NECWKKB2A3fBupkJYxOiQr/FPz?= =?us-ascii?Q?cZ4AKU3F/5WYfArZgLQfPFJhCrHlGfhEt910X7mm9lN/aIvlM9+VyWVEgyir?= =?us-ascii?Q?kmU9Lo+Mgjdm3nsOTthjCVU9GdTAH5D8ftSdmMRxxxm++6nRq4MkqQU42gJq?= =?us-ascii?Q?YCHtxLqv3xyAZeeQ62dQP44vpodg2kIxf5CAcHdAYSNmMDpXG95gBCSpRCw?= =?us-ascii?Q?=3D=3D?= X-Microsoft-Exchange-Diagnostics: 1;SN1PR0201MB1791;5:fx8ozzj94eCVmQjBBSoBidmlcEhoAU2kwkCzoQdS3HKvs/OPqlb8QganRcBd3MIEzly/vnqHgYtOTxpB4295laLXhqRsHYzHhXfsEdHcM+LEjWmyep6RKLHj7Rzpf4GHEehJTTcDiJJq6CMPTXVwkgss+AV2x7vLTRlLxXW2wOaGss37Uis8+0expRzEEmYv;24:emGpiF0EUFepmUCMQfVeCjKZJQx3Xeh+llOAy1qH1m+0iv40cGWHCdP4mlJ9xay7kMduFRAKOIs8Zx9ZZcYFC8gh78XF58XmDdkIcQvBZ9I=;7:wSQNQ08g81iHgKd9RctYzcxcSwNZjv/wiCkyFyf4g/7SZ/3wrQ3teH6R880DhLeIs2qs/gD+fXTWdNXf4OAThvORxNsvoEX1Sif6lyGCJ9Z+M/Nav12fI2ujIIXnuxtBkFHNb3gKh9OPgfBLa9LGMwSCiBMOmGwEKwNKwz47ijIVtuuEHnkF7z2O/q0mMlaGmIWE7Jh+4DkAfHSyZhgCaQa5vInR9ncbIF8J4eSn5DI= SpamDiagnosticOutput: 1:23 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: zend.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 25 Apr 2016 07:42:48.7681 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN1PR0201MB1791 Subject: Re: [PHP-DEV] [RFC] PHP Attributes From: dmitry@zend.com (Dmitry Stogov) --------------050808030000050405020508 Content-Type: text/plain; charset="utf-8"; format=flowed Content-Transfer-Encoding: 7bit On 04/22/2016 06:39 PM, guilhermeblanco@gmail.com wrote: > > On Fri, Apr 22, 2016 at 3:07 AM, Dmitry Stogov > wrote: > > > > On 04/22/2016 04:05 AM, guilhermeblanco@gmail.com > wrote: >> Hi Dmitry, >> >> As a previous suggester of metadata information built-in into >> PHP, and also one of developers of the most used metadata library >> written in PHP, I understand this feature implementation requires >> several design decisions and also a good understanding of >> specific situations users may require. >> >> While I am a strong supporter of a more robust solution, this is >> already a good start. >> A few things I'd like to ask for my own understanding and also >> suggestions too: >> >> 1- I understand you took a minimalistic approach towards a "dumb" >> implementation for attributes (when I mean "dumb", the idea here >> is towards a non-OO approach). Can you explain your motivations >> towards this approach? >> >> I see two distinct approaches of implementation for this feature. >> Both of them have some common demands, like lazy initialization >> of metadata. Here they are: >> >> - Simplistic approach, which lets consumers of the feature do all >> the work related to validation, assertion of valid keys, values, etc >> This does not invalidate the ability to leverage of some features >> that a more robust implementation demands. >> >> - Robust approach: language takes the burden of instantiating >> complex structures, validating, assertion of valid keys, values, >> if this complex structure is allowed to be instantiated in that >> given class, method, etc. > > I didn't exactly understand what do you suggest. > If you are talking about Attribute objects initialization during > compilation - this is just not possible from implementation point > of view. > Now attributes may be stored in opcache SHM and relive request > boundary. > Objects can't relive requests. > > > > I know that object instances are not cross-requests. Explicitly, I > mentioned that both approaches require lazy-initialization (which > means, whenever you call getAttributes() or getAttribute()). > > What I mentioning is that your approach is basically a new key/value > syntax that are used specifically for Attributes. We could easily turn > this into a more robust approach if instead of defining key/value > pairs, we instantiate objects or call functions. You already > demonstrated interest to support <> reusing the imports > (which is our biggest headache in Doctrine Annotations), so why not > issue constructor or function calls there? That would simplify the > work needed for consumers and also add room for later improvements. > So basically in this example: > > use Doctrine\ORM; > > <> > class User {} > > $reflClass = new \ReflectionClass("User"); > var_dump($reflClass->getAttributes()); > > We'd be changing from this: > > array(1) { > ["Doctrine\ORM\Entity"]=> > array(1) { > [0]=> > string(4) "user" > } > } > > Into this: > > array(1) { > ["Doctrine\ORM\Entity"]=> > object(Doctrine\ORM\Entity)#1 (1) { > ["tableName"]=> > string(4) "user" > } > } As I showed already, it's very easy to do this transformation at higher layer. $reflClass = new \ReflectionClass("User"); $attributes = $reflClass->getAttributes() foreach ($attributes as $key => &$val) { $val = new $key(...$val); } var_dump($attributes); Construction objects directly in Reflection*::getAttributes() method, doesn't make significant benefits and even makes limitation. > > >> >> 1- Your approach is basically defining an array. Could you >> explain your line of thinking on why you didn't consider a syntax >> like the one below? >> >> <["key" => "value"]> >> class Foo {} > I didn't try to invite new syntax. Just completely took it from HHVM. > > > My idea was based on your current proposal, which is basically a way > to define key/value pairs. > If you decide to go minimalistic, that is probably my best line of > thinking. > > > >> >> 2- I see that you added support over functions, classes, >> constants and properties. According to the RFC, getAttributes() >> was added over ReflectionFunction. Is there a reason why support >> was not added to methods (ReflectionMethod extends >> ReflectionFunctionAbstract, which was not mentioned on RFC)? Any >> reason to not support it in function/method parameters? > ReflectionMethod is a child of ReflectinFunction, so it's supported. > > Attributes are allowed for the same entities as doc-comments (they > are not allowed for parameters) > > > I was asking if there was a purpose to not support Attributes over > ReflectionParameter. Example: > > class Foo { > public function bar(<> Bar $bar) : bool { > // ... > } > } > > $reflClass = new \ReflectionClas("Foo"); > $reflMethod = $reflClass->getMethod("bar"); > $reflParameter = $reflMethod->getParameters()[0]; > > var_dump($reflParameter->getAttributes()); I understood, we may add this ability later. > > > >> >> 3- Did you put any thought on inheritance? What I mentioned in >> comment #1 is even smaller than what you implemented in RFC. >> Assuming you keep the RFC approach, did you consider support >> overrides, inherit, etc? > > In my opinion, attributes don't have to be inherited. > If you think differently - please explain your point. > > > Of source I can. > A simple case would be to increate visibility of the inherited > property. It was declared in a parent class as protected, but now you > want public, and you still want to keep all parent defined Attributes. Very questionable. If you redefine property, it shouldn't inherit attributes. > Another example is like we do in Doctrine. We support a callback > system which we named as lifetime callbacks. Pre-persist is one of > them, which is called every time a given Entity is about to be > persisted into DB. When you're dealing with inheritance, you can > potentially override the method content and you still want to trigger > the same operation as if it was untouched. Example: > > use Doctrine\ORM; > > trait Timestampable { > protected $created; > protected $updated; > > <> > public function prePersist() { > $this->created = $this->updated = new \DateTime("now"); > } > > <> > public function preUpdate() { > $this->updated = new \DateTime("now"); > } > } > > <> > class User { > use Timestampable; > > public function prePersist() { > // Add my custom logic > } > } > The implication is that through a simplistic approach, inheriting (or > overriding) is not clear and I can't figure it out an easy way to > achieve that. > Now if we go towards calling a function or class constructor like I > mentioned before, then we could easily build structures like > __Inherit, __Override, etc. It's definitely, not clear when attribute inheritance make sense and when completely not. For example, if we mark some method to be JIT-ed, it doesn't mean that we like to JIT methods of all children. So, I prefer not to do inheritance at all. The higher layers may emulate "inheritance" of some attributes their selves (like you do this with doc-comments). > > >> >> 4- I understand that a more robust attribute solution would be >> required to achieve this, but one of the biggest advantages of >> AOP is the ability to perform custom logic before, after or >> around... However, I don't know if any kind of triggers came in >> your head or are planned as a future RFC. >> Let me highlight one example: Every time a class, property or >> method is called that is annotated as <>, I would >> like to issue an E_USER_DEPRECATED warning. A trigger-like >> solution would be required. Did this concept came to your mind? > This is not a subject of this RFC. > Attributes provides a storage for metadata, but don't define how > to use them. > Especially, for your use-case: > 1) it's possible to create preprocessor that embeds corresponding > trigger_error() call > 2) it's possible to write a PHP extension that plugs-into compiler > chain and checks <> attribute for each compiles > function, then sets ZEND_ACC_DEPRECATED flag > 3) It's also possible to override DO_FCALL opcodes and perform > checks there (this is inefficient) > > > With this simplistic approach, I agree there's 0 value into > considering this. > However, taking a more robust approach would potentially open this > possibility through a simpler extension. You saw, Sara named even this proposed solution a bit over-designed. it make no sense to implement all functionality at language level. Actually, keeping simple base interface, opens doors for more use-cases. Thanks. Dmitry. > > Thanks. Dmitry. > > >> >> >> >> Regards, >> >> On Thu, Apr 21, 2016 at 7:44 PM, Dmitry Stogov > > wrote: >> >> >> >> On 04/22/2016 02:16 AM, Dominic Grostate wrote: >> >> >> This is amazing. It would actually allow us to implement >> our automated assertions ourselves, as opposed to >> requiring it within the language. >> >> this was the idea - to give a good tool instead of >> implementing every possible use-case in the language. >> >> Could it also support references? >> >> <> >> function foo($a) { >> >> } >> >> yes. "&$a" is a valid PHP expression. >> >> If you plan to use this, I would appreciate, if you to build >> the patched PHP and try it. >> The early we find problems the better feature we will get at >> the end. >> >> Thanks. Dmitry. >> >> >> On 21 Apr 2016 10:13 p.m., "Dmitry Stogov" >> >> >> wrote: >> >> Hi, >> >> >> I would like to present an RFC proposing support for >> native >> annotation. >> >> The naming, syntax and behavior are mostly influenced >> by HHVM >> Hack, but not exactly the same. >> >> The most interesting difference is an ability to use >> arbitrary PHP >> expressions as attribute values. >> >> These expressions are not evaluated, but stored as >> Abstract Syntax >> Trees, and later may be accessed (node by node) in >> PHP extensions, >> preprocessors and PHP scripts their selves. I think >> this ability >> may be useful for "Design By Contract", other formal >> verification >> systems, Aspect Oriented Programming, etc >> >> >> https://wiki.php.net/rfc/attributes >> >> >> Note that this approach is going to be native, in >> contrast to >> doc-comment approach that uses not well defined >> syntax, and even >> not parsed by PHP itself. >> >> >> Additional ideas, endorsement and criticism are welcome. >> >> >> Thanks. Dmitry. >> >> >> >> >> >> -- >> Guilherme Blanco >> Lead Architect at E-Block > > > > > -- > Guilherme Blanco > Lead Architect at E-Block --------------050808030000050405020508--