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

Reply via email to