Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:116821 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 84967 invoked from network); 5 Jan 2022 19:28:19 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 5 Jan 2022 19:28:19 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id F18A01804F8 for ; Wed, 5 Jan 2022 12:35:50 -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.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,HTML_MESSAGE, RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_PASS 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-ua1-f41.google.com (mail-ua1-f41.google.com [209.85.222.41]) (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 12:35:50 -0800 (PST) Received: by mail-ua1-f41.google.com with SMTP id p1so593166uap.9 for ; Wed, 05 Jan 2022 12:35:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=rYdvgIXCpfbJ1h9jwTtZUmcH3QTANDIWWO5Xq8ln124=; b=ISvOqxpio8Rae3EM2O/wKjPhpBh/v8cTb9FpyqBthU9zS4ABanxGL5sArhXDcW3v4X E6fQGrd7IYKIxH2dsY7v2yQcPpG8LchDUFwcRnTvBCB1Din1uZLujB45Vj7KoXVJHNQY Rj2xlnciwpE56ce/ZvGrYnef5l/92Dm987IrYvCu0D6CbBOv9iJHIlSsVEp2VUCaxFwZ MqktO2VI7YC6JDRb7rY+jo1QLIb2ydNZ7yw/MHc2eh0r/WfQ3qvcqfD0puldZ8wMMz6E lGsN5+mXEHo3fvrEXXEml2sxPuPFtw6//lZNS6qa76Qyupdxry8hvqDx0ydkp1cflZpp yL3g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=rYdvgIXCpfbJ1h9jwTtZUmcH3QTANDIWWO5Xq8ln124=; b=ctJpzm2fdfMTxMR4vwunOyGYJ1GOzS7Bd2hJlrzJ6XC45gA9b1iKpRdidJZVV75QzA ggQXMc3RBNA+xauLsmm6KAaigYsjc6Xq/wCqjKfQX+L+fIZTRuv5AWqminN92Zy6Qgxl IxLbEWNz0J+ThBiGdYn3jo3Ht3beoUR0m3YmP3bJklXF7hNu6wH190Jbz7wAQTmmlJhy MxKLZTNbDKockLq0i4MQHEI82dgJzIFg1EWogIlFFRws/7iUNvcgi4PMQ0xcwm0/vLtm 8aah3Io6ebXAY0SKfcbYCxJ+TYEROV6pRxfMkQgyFT7qsiG0S3xgD7k5q8pmwWXH+k1+ Lg+g== X-Gm-Message-State: AOAM531AyECCEszh2PP9Pw69fQaQW79PZbas8VWop/1nL3nI154oG3ks NXZwoOf5CBQOlw2p06MU9u1TPTcGWd6h/2IRERs= X-Google-Smtp-Source: ABdhPJwVggLldfqNuE78LCw1cyngXY4Prdg3JxXS6QuIia4hlZvd++lrU1/9lOHIIqP5IHnPzdyoTEo6NEpFeatXJgw= X-Received: by 2002:a67:bb01:: with SMTP id m1mr18765545vsn.48.1641414949751; Wed, 05 Jan 2022 12:35:49 -0800 (PST) MIME-Version: 1.0 References: <1641335738.195767637@f174.i.mail.ru> In-Reply-To: Date: Wed, 5 Jan 2022 15:35:37 -0500 Message-ID: To: David Gebler Cc: Kirill Nesmeyanov , internals Content-Type: multipart/alternative; boundary="000000000000024d7a05d4dbb38e" Subject: Re: [PHP-DEV] RFC: Trait expects interface From: chasepeeler@gmail.com (Chase Peeler) --000000000000024d7a05d4dbb38e Content-Type: text/plain; charset="UTF-8" On Wed, Jan 5, 2022 at 2:17 PM David Gebler wrote: > On Tue, Jan 4, 2022 at 10:35 PM Kirill Nesmeyanov wrote: > > > How relevant do you think this idea/proposal is? And what possible > > problems or solutions will this entail in the future? > > > > I'm not convinced there's a reasonable need for it. The very nature of > finding yourself in a situation where you want any class using a trait to > also require other things outside the trait kind of suggests you really > want to be using interfaces or abstract classes anyway. > > There is a similar concept for what I think you're trying to achieve in > Java, though, which could also be useful in PHP if it was feasible within > the engine - the ability to provide a default method implementation on > interfaces themselves. > > Short of that, we can already effectively get there with the tools we have; > an abstract class can use a trait and define abstract or concrete methods, > and in doing so can implement one or more interfaces. Obviously traits can > also declare abstract methods but I assume it's the identity/type aspect of > an interface you want here which isn't satisfied by that approach. > > Also worth noting, although I can't say I'm familiar with the mechanics of > traits in PHP's implementation, my understanding has always been that > they're effectively compiler-level copy and paste in to a class so I'm not > sure what interfaces are implemented by the class (or conversely allowing a > trait to implement an interface) would be readily achievable. > > That's my two cents, good luck with whatever you're trying to do anyway. > > - David > > > > -- > > Kirill Nesmeyanov > 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. 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. -- Chase Peeler chasepeeler@gmail.com --000000000000024d7a05d4dbb38e--