Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:116823 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 92621 invoked from network); 5 Jan 2022 21:57:37 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 5 Jan 2022 21:57:37 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 43F0A1804A7 for ; Wed, 5 Jan 2022 15:05:10 -0800 (PST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_LOW,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL, SPF_HELO_PASS,SPF_NONE autolearn=no autolearn_force=no version=3.4.2 X-Spam-ASN: AS19151 66.111.4.0/24 X-Spam-Virus: No X-Envelope-From: Received: from out3-smtp.messagingengine.com (out3-smtp.messagingengine.com [66.111.4.27]) (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 ; Wed, 5 Jan 2022 15:05:09 -0800 (PST) Received: from compute6.internal (compute6.nyi.internal [10.202.2.46]) by mailout.nyi.internal (Postfix) with ESMTP id 326155C013C for ; Wed, 5 Jan 2022 18:05:09 -0500 (EST) Received: from imap43 ([10.202.2.93]) by compute6.internal (MEProxy); Wed, 05 Jan 2022 18:05:09 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to:x-me-proxy :x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm1; bh=0EQ51q eLd7Ayu8wPiM2x250nhEoJDPFEJQUqEhq/llA=; b=khJ2LbrtMO+0TTh5jBWgFv Mw91INsa0EnXHLRcknZ84n/QcL6Ee53Q081X3IWrdQTSKQ8UYcpsjDJmbBSDzR1z +vPppDKq9/OQeDZiKiaDoObAwkcR8eYVVB/BfkGQYMpB+kbs889se8OaFDkRXFhS XsJy1sYHPVe6WcW5Ce8iusLMvljUVoUEACtosm7EcifXIxVHEYWUb3bLgXvT5870 vDpoiypW/kmbNp/J95ySHji0sxa/ZS84mvABShRSjMOL6wEUoq0ADBVpO2x13udf hu+m53vBaSAyEnMMYnRgnzZSUStz+XXC4OaPE0MjQ5+YehYLdH0kubcCjgS/jdeA == X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvuddrudefjedgkeegucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhepofgfggfkjghffffhvffutgesthdtredtreertdenucfhrhhomhepfdfnrghr rhihucfirghrfhhivghlugdfuceolhgrrhhrhiesghgrrhhfihgvlhguthgvtghhrdgtoh hmqeenucggtffrrghtthgvrhhnpeeglefgkeduiedvvdetffeujefftdfhjeeiveehgfff keduveektddvledvvdfffeenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmh grihhlfhhrohhmpehlrghrrhihsehgrghrfhhivghlughtvggthhdrtghomh X-ME-Proxy: Received: by mailuser.nyi.internal (Postfix, from userid 501) id AE4FDAC0E99; Wed, 5 Jan 2022 18:05:08 -0500 (EST) X-Mailer: MessagingEngine.com Webmail Interface User-Agent: Cyrus-JMAP/3.5.0-alpha0-4526-gbc24f4957e-fm-20220105.001-gbc24f495 Mime-Version: 1.0 Message-ID: <5a4aebf8-e592-4517-8930-d18b112ef1fd@www.fastmail.com> In-Reply-To: References: <1641335738.195767637@f174.i.mail.ru> Date: Wed, 05 Jan 2022 17:04:47 -0600 To: "php internals" Content-Type: text/plain Subject: Re: [PHP-DEV] RFC: Trait expects interface From: larry@garfieldtech.com ("Larry Garfield") On Wed, Jan 5, 2022, at 2:35 PM, Chase Peeler wrote: > First, I'm someone that mainly uses traits to implement the functionality > defined in an interface. I think that's one of the best uses for them. > However, I'm personally not a huge fan of overly restrictive things. For > instance, while there are definitely some use cases for them, I need a > REALLY good reason to justify making a property/method private instead of > protected, or making a class final. I am much the same. > As such, I think this would be better if it didn't throw a fatal error. > When you make it optional, however, I think you are left with something > that can be handled with an attribute just as well as a new keyword: > #[Expects('MyInterface')] > trait foo { } > > However, there might be value in generating a notice/warning, and I think > that would require a keyword, correct? (Not that up to speed on > annotations). Another option might be two support two new keywords: > requires and expects. The former would throw an error if the interface > isn't implemented while the latter will throw a warning/notice/nothing. > > Another option (and I haven't thought about this one enough to decide if I > like it) would be to have the expected interface automatically implemented > in the using class. This would allow the trait to be written under the > assumption it has access to the methods defined in the interface, and will > then throw an error if any of the methods are not implemented in the using > class: > > interface foo { > function a(); > function b(); > } > > trait bar expects foo { > function c(){ > return $this->a() + $this->b(); > } > } > > class baz { > use foo; > } > > The above would throw an error since a() and b() are never implemented and > baz is implementing the foo interface. You can currently get the same > behavior if you define a() and b() as abstract in the trait. However, this > doesn't give you the added benefit of utilizing the interface automatically > within the type system. The more I think about it, the less I like this > idea, since it doesn't require that much additional work to make the code > clearer by explicitly implementing the interface on the class if you want > it implemented. However, I'll go ahead and leave it here because it might > help generate some other ideas. I... still don't see any use in this annotation. Stepping back and ignoring the syntax for a moment, there's two different things here: 1. "This trait expects to be used in a class that has these other methods on it". 2. "This trait mostly/fully fulfills interface X, because it has methods a, b, and c." For point 1, we already have that. It's called abstract methods in traits. This is a solved problem that requires no further resolution. At best it would be a shorthand to copying a few methods from an interface into the trait and sticking "abstract" in front of them. I really don't see a need for that. For point 2, that's mainly useful as a way to signal to other developers "hey, this trait has all but one method of the LoggerInterface, that's how you'd use it", and to signal static analyzers and refactoring tools the same thing so that they can be auto-updated if you tweak the interface. I can see a use for point 2, and it would make my life a bit easier, but it's overall not high priority. --Larry Garfield