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

From: Date: Sat, 08 Nov 2025 10:19:32 +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-129146@lists.php.net to get a copy of this message
On Friday 07 November 2025 20:19:37 (+01:00), Rowan Tommins [IMSoP] wrote: > On 07/11/2025 17:05, Spencer Malone 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". > > > Hi and welcome :) > > In general, I prefer explicit code over implicit, so wouldn't be an > enthusiastic supporter of this [...] > However, I though it worth mentioning that PHP has one implicit > interface already: any class with an __toString() method magically > implements Stringable. I've never really understood why, or why that > interface even exists; but at least having a general concept of > "implicit interface" would make it less magical. > Good thinking, inspiring, in my eyes that __toString() magically, both in the method as in the inverse of the direction towards the Stringable interface definition, is rather stemming from the needs of some object oriented PHP framework authors IIRC. In terms of it as a historical artifact to learn from or take something away from it for similar implicit interfaces, I'd like to add that I find it rather explicit (like a parental advisory sticker on a CD jewel case) due to the inability of PHP to resolve such (internal) interfaces at place of use (the implements keyword) while there was no problem with the implicit magic method. This is perhaps why I as well have very little understanding what that single instance has brought to the table finally, it appears to stand in the way much too often for me on the observable surface. The only hope I nevertheless had with it is, that it would have helped to solve the problem of __toString() fatalling in the engine. So Stringable/object{__toString(): string} is certainly a very special example in its very own not as a _magical_ special case, but it is a fundamental special case every programming language that has "output" has to solve. Not having any output would solve the turing problem by its higher math, but such machines also have effectively undefined themselves and by that any programming language. That problem is inherit with output and it is the formatting of output, even if it is only dumping the content of the process registers. What we can't see does not exist. So every programming language at that point must re-invent itself somehow, as it certainly does not compile recursively, but rather has the concepts of compiletime, runtime, whatnottime and the recursion, direct or indirect, often a property stemming from these, it (recursion) is always a thing, too. > 12. Recursion is the root of computation since it trades description > for time. Unless strict normative rules are given by the design to prevent that (e.g. to make things maintainable safely in the longtime), but every extension will add, not remove, so longtime or eternity often only remains the idea, bugs and regressions the reality along the road of success. If we take output then for a given, we have to solve this problem at its core, otherwise we can't built upon it. This is where yours mentioned implicit Stringable interface comes into play. For those Framework authors it certainly was enough to given them a way to go from a method pointer ("__toString") or a memory pointer (the string), from a memory object to a PHP language classlike object, e.g. by declaring the type with a function or method parameter (in) or return value (out). Regardless if only compiled once to its executable form, ErrorException (PHP 5.1), or as in PHP userland compiled, interpreted and re-compiled until it gets there: What do you do when that error is to be handled and the error handler is in userland (or at compile time) and includes (or has) more code to be evaluated while handling the error still on the engine level? See in PHP thanks to the scripts, we have this inane recursion problem. This is a bit like heart surgery on the open heart, the pump is still pumping and one wrong cut everything can bleed out. The doctor may survive, so in terms of software, there is not much need to really know what we are doing here and can defer some work until later. In real life this causes grave injuries if not deaths. How successful such an implicit Stringable interface (PHP 8.0 IIRC) was in this sense I do not know. I do not even know if the introduction of Stringable has been discussed afterwards in that regard. But I'm derailing, what I wanted to prolong on is, that Stringable in itself as an "implicit" interface as you have rightfully mentioned, is certainly touching many more parts than the suggested "implicit interface" by Spence Malone would need to care about. So what are other examples? Tagging (with empty interfaces) often comes to my mind then, but all interfaces, empty or not, also have the probem of the loading order in PHP. At place of use, where they would shine, requires not only to explicitly define them (good!), but also to explicitly have them loaded. So there perhaps is still a problem in PHP core to get compilation and execution into a quite better order in the sense of their arrangement to make use of the language with the runtime. The framework authors didn't had that problem, because they voided it by separating each classlike into its own file (object) and then let having PHP/SPL resolve the loading order (a.k.a. class autoloading). At the core we can still see that problem as separating each classlike into an object (file) of its own requires preproduction (those are actually deployables, so we're not programming any longer but have longtime stopped and already are building the artifacts.) If there is something to strengthen, then it is the ability of PHP developers to program in PHP, not to waste time thinking about that they need to learn some special technique how to arrange their code later on so that it fullfills some dependency, theirs dependency managers and then call that the art of doing module management. This is all longtime afterards and therefore always inherits any previous flaw at the languages core every PHP framework author intends to not address at all. So in my opinion your raise of the dynamics from explicit to implicit and vice-versa can bring interesting aspects to the table regardless which style each of us is currently thinking to prefer, but as you rightfully raised, PHP core developers should also confront themselves on how to pick up the loose ends we still have while new authors make useful suggestions to extend language-level intermediates. From PHP history, IMHO (and regardless how I use or not use them), Traits are a key milestone in this way of PHP design done right for me. The proposal aligns well for me in that regard. Stringable on the other hand, a bad example of everything but making problems in core and use of the PHP language itself more visible; and that is often a good thing, see the output problem above I mentioned, my current understanding is that we always inherit that on computer systems and when programming machines. So as long as we can get output, we can benefit. Naturally we benefit from explicit output much more then from implicit one - until otherwise. > 4. Every program is a part of some other program and rarely fits. my 2 cents, - h.k.

« previous php.internals (#129146) next »