Hi, > allow using string|Stringable to express string|object-with-__toString()
That goal is expressed in a technical way, rather than a functional one. I have the feeling that addressing the goal: "Can I represent/cast variable $str as a string" would address a broader, yet much more useful, scope. string|Stringable: 1. Denotes a list of types, not a capability as "stringable" would as a virtual type (like iterable). It somewhat contradicts the principle of knowing the *type* vs knowing what we can do with it. 2. Is incomplete in terms of what can be "represented as a string". The Stringable interface used alone tells there is a __toString() method. Therefor, we should expect it to be used to call the __toString() method explicitly: function test(Stringable $object) { \strtoupper($object->__toString();) // do something with __toString(); } ... in order to be consistent with what interfaces are meant. If mainly used for string casting capability, then it will only match objects and not all the other types that can be casted as string. A virtual "stringable" type (that would be similar to "iterable)" would, IMHO, be of a bigger benefit if it is to denote the fact that "a variable can be transformed to a string". By design, when a variable is declared as "iterable", you know you can foreach() on it now, but also on other yet-to-be-implemented concepts that would support foreach looping. Think about it as if generators would have appeared after "iterable" keyword and then, added to it. > Adding a new stringable special type (like iterable, callable, etc.) is not considered in this RFC because it would require adding a new reserved keyword in the language. This would break BC more heavily and would defeat goal #2 mentioned previously (ability to polyfill on PHP7.) It's perfectly fine to add a new reserved keyword in the language, and a major version is absolutely the best moment for it. Not sure how much more break would be implied by a keyword, vs the interface. As it is presented, Stringable alone seems of very little use as compared to union like "string|Stringable", so using the polyfill in a version of PHP that does not support union does not seem to make sense. What is the real advantage of adding this to the core, rather than some FIG/PSR standard? This would be compatible in both current versions of PHP and next ones at the same time. This RFC would also introduce a very new concept, which seems nice at a first glance, but a bit nasty too: class Foo { /** @deprecated */ public string __toString() { throw new \Exception("Foo should not be casted to string, you should now..."); } } The above would imply that "Foo implements Stringable" unconditionally: without opt-in, but also without opt-out! It would also be the only one case of classes declared without "implements" that would still implement an interface: quite contradictory and hacky! It would be less "hacky" if a broader concept (let's say "Signature"?) would exist for checking at runtime the availability of a method without requiring an interface to be implemented, e.g.: Option 1: By introducing the "signature" keyword: signature CanCommit { public function commit(); } used like this: if ($object instanceof CanCommit) { $object->commit(); } Option 2: By introducing an extra meaning to keyword "implements": interface CanCommit { public function commit(); } used like this: if ($object implements CanCommit) { // Checking at runtime that $object's class would comply to interface CanCommit $object->commit(); } If this, or a similar concept would exist, one could just declare a signature for __toString() and we wouldn't have the incoherence that this RFC introduces. Another, also broader, approach would be to implement a global way to check "castability" to type X: function foo((string) $stringable) { // Type not enforced, but possibility of casting checked } I'm aware that this RFC addresses a small goal, but accepting lot of small changes compared to bigger ones with a broader vision could lead to even more inconsistencies in the core in the longer run. Regards, Patrick