Re: Pre-RFC proposal: opt-in implicit interfaces / structural typing

From: Date: Fri, 07 Nov 2025 17:51:31 +0000
Subject: Re: Pre-RFC proposal: opt-in implicit interfaces / structural typing
References: 1  Groups: php.internals 
Request: Send a blank email to internals+get-129133@lists.php.net to get a copy of this message
Hi Spencer, > On Nov 7, 2025, at 12:05, Spencer Malone <malone.spencer@gmail.com> wrote: > > Hey all! Long time browser, first time emailer. I wanted to start a pre-RFC discussion on the > proposal of opt-in implicit interfaces / structural typing / "golang style interfaces". > > I have an early mostly working POC at > https://github.com/php/php-src/compare/master...SpencerMalone:php-src:implicit, > and was curious if this was an idea that could get any traction as an RFC? > > For those who don't want to open the link, it's essentially: > > ``` > implicit interface Drawable { > public function draw(): void; > } > > class Circle { > public function draw(): void { > } > } > > assert((new Circle()) instanceof Drawable); // This would be true > ``` > > There is some previous art around here in the form of... > > https://wiki.php.net/rfc/protocol_type_hinting - I > couldn't find any discussion on this other than reading that the author withdrew all their RFCs > for unrelated reasons I think? Some of the core ideas here I think are still relevant, although in > my implementation I chose to use syntax that adds a keyword onto the interface rather than at the > call sites because I wanted to provide the ability for interface definers to keep their interfaces > as explicit if they wanted, as well as... Well honestly, adding angle brackets around objects feels > like a syntax misstep since that pattern is very associated with generics in my mind. I could be > convinced of this though if that's the syntax people prefer. > > https://externals.io/message/115554#115603 - Convinced me that > others may want this as well, although again that proposed syntax ended up stepping on the toes of > attributes. I do think this does a good job of explaining _why_ I want this. > > - Spencer I think this is an interesting idea, but personally, I would prefer to see classes always explicitly declare their interfaces. An interface is a contract, and implementing the interface is agreeing to conform to the contract. Just because a class has the shape of an interface doesn't mean it follows the contract. implicit would probably be most useful for very simple interfaces, but those are exactly the kind of interfaces that could be misinterpreted. For example, this poorly designed class: ``` class DeckOfCards { public ?Card $mostRecentlyDrawnCard; public function draw() : void { ... } } ``` should not be instanceof the Drawable interface, because it doesn't conform to the contract, even though it structurally matches. Perhaps slightly less torturously, ``` class Canvas { public array $contents; //list<Drawable> private CanvasInternalRepresentation $internalRepresentation public function draw() : void { ... update the canvas's internal representation ... } public function data($imageType) : string { .. } // return binary blob of $imageType data from the internal representation } ``` This Canvas takes a list of Drawables and uses a draw() method to update its internal representation. But it itself is not Drawable (let's say, because Canvas can't be nested for whatever reason). In real code, there's probably a lot of things that structurally would conform to some sort of simple Cache/Cacheable or Request/Response interface but for reasons wouldn't obey whatever implied contract those interfaces would demand. In my opinion, a better solution would be to allow for extensions that allow declaring interface conformances. e.g. ``` extension Circle implements Drawable { // We have now explicitly declared that Circle is a Drawable and conforms to its contract. // This extension body is empty because Circle already has a conforming draw method, // but if it didn't, we could add one here and it would be treated as part of the Circle class. } ``` Of course, this would be a much more involved proposal than implicit interfaces, which does have elegance in its simplicity. -John

« previous php.internals (#129133) next »