Hello everyone,
as announced last week, I'm officially opening a discussion for adding a
"Stringable" interface to PHP 8.
The RFC and its rationale are presented here as required:
https://wiki.php.net/rfc/stringable
The patch is found on GitHub, where some discussions happened already, you
might be interested in having a look:
https://github.com/php/php-src/pull/5083
TL;DR, I think we need an interface to allow passing objects with a
__toString() method in a type-safe way, using the string|Stringable type.
Here is the stub of the proposal:
interface Stringable { public function __toString(): string; }
I invite everyone to review the RFC before commenting here as I tried to
sum up considerations that some already had before and that you might have
too.
Cheers,
Nicolas
On Wed, Jan 22, 2020 at 4:47 PM Nicolas Grekas nicolas.grekas+php@gmail.com
wrote:
Hello everyone,
as announced last week, I'm officially opening a discussion for adding a
"Stringable" interface to PHP 8.The RFC and its rationale are presented here as required:
https://wiki.php.net/rfc/stringableThe patch is found on GitHub, where some discussions happened already, you
might be interested in having a look:
https://github.com/php/php-src/pull/5083TL;DR, I think we need an interface to allow passing objects with a
__toString() method in a type-safe way, using the string|Stringable type.
Here is the stub of the proposal:
interface Stringable { public function __toString(): string; }
I like the fact that you automatically add the string return type to
existing methods to avoid BC break problems.
Given that the engine enforces this with special code right now, i believe
its a nice improvement to happen
automatically.
I invite everyone to review the RFC before commenting here as I tried to
sum up considerations that some already had before and that you might have
too.Cheers,
Nicolas
On Wed, 22 Jan 2020 at 15:47, Nicolas Grekas nicolas.grekas+php@gmail.com
wrote:
Hello everyone,
as announced last week, I'm officially opening a discussion for adding a
"Stringable" interface to PHP 8.The RFC and its rationale are presented here as required:
https://wiki.php.net/rfc/stringable
I'm still unconvinced on this one, but I was digging into some of the uses
you linked to, to understand why it might be used.
The background to the Symfony Validator one makes for some interesting
reading: https://github.com/symfony/symfony/pull/31083 and
https://www.drupal.org/project/drupal/issues/3029540
It seems that Symfony always intended this particular parameter to be a
string, but couldn't enforce that until PHP 7; Drupal abused it by passing
in an object, which happens to be stringable but have special behaviour in
the templating layer, leading to a compatibility break between the two
projects. In a sense it's just luck that the object in question implements
__toString(), rather than being a completely unrelated object, since Drupal
relies on it being passed back out unmodified.
Nonetheless, it's an interesting use case, and it's interesting to
speculate whether it might have been designed how it is anyway without that
history. Ultimately, the contract is that (string)$foo->getMessage() won't
error, which is ... kind of useful, I guess?
Regards,
Rowan Tommins
[IMSoP]
Le mer. 22 janv. 2020 à 20:03, Rowan Tommins rowan.collins@gmail.com a
écrit :
On Wed, 22 Jan 2020 at 15:47, Nicolas Grekas <nicolas.grekas+php@gmail.com
wrote:
Hello everyone,
as announced last week, I'm officially opening a discussion for adding a
"Stringable" interface to PHP 8.The RFC and its rationale are presented here as required:
https://wiki.php.net/rfc/stringableI'm still unconvinced on this one, but I was digging into some of the uses
you linked to, to understand why it might be used.The background to the Symfony Validator one makes for some interesting
reading: https://github.com/symfony/symfony/pull/31083 and
https://www.drupal.org/project/drupal/issues/3029540It seems that Symfony always intended this particular parameter to be a
string, but couldn't enforce that until PHP 7; Drupal abused it by passing
in an object, which happens to be stringable but have special behaviour in
the templating layer, leading to a compatibility break between the two
projects. In a sense it's just luck that the object in question implements
__toString(), rather than being a completely unrelated object, since Drupal
relies on it being passed back out unmodified.Nonetheless, it's an interesting use case, and it's interesting to
speculate whether it might have been designed how it is anyway without that
history.
Ultimately, the contract is that (string)$foo->getMessage() won't
error, which is ... kind of useful, I guess?
Totally, you got it right I think.
Does the RFC trigger any other comments?
Is the patch OK to people that know the engine well?
I'll open the vote on February 6th there are no objections.
Thank you,
Nicolas
On Wed, Jan 22, 2020 at 4:47 PM Nicolas Grekas nicolas.grekas+php@gmail.com
wrote:
Hello everyone,
as announced last week, I'm officially opening a discussion for adding a
"Stringable" interface to PHP 8.The RFC and its rationale are presented here as required:
https://wiki.php.net/rfc/stringableThe patch is found on GitHub, where some discussions happened already, you
might be interested in having a look:
https://github.com/php/php-src/pull/5083TL;DR, I think we need an interface to allow passing objects with a
__toString() method in a type-safe way, using the string|Stringable type.
Here is the stub of the proposal:
interface Stringable { public function __toString(): string; }I invite everyone to review the RFC before commenting here as I tried to
sum up considerations that some already had before and that you might have
too.Cheers,
Nicolas
I'm wondering whether it could make sense to automatically implement this
interface for all classes that define __toString(). Explicitly implementing
the interface is useful for the transition period (where old PHP versions
also need to be supported), but when considering only PHP 8 support, I
think it may make sense to implicitly implement the interface. If the
__toString() functionality also works fine without implementing the
interface, and there's probably only going to be relatively few consumers
of the Stringable type, it will likely be quite common that the interface
will not get implemented...
Automatically implementing interfaces based on implemented methods could
also be a general language feature (see Go interfaces for example), but
likely not one we're interested in having in it's full generality. In this
particular case, it seems useful though.
Regards,
Nikita
Le lun. 27 janv. 2020 à 10:19, Nikita Popov nikita.ppv@gmail.com a écrit :
On Wed, Jan 22, 2020 at 4:47 PM Nicolas Grekas <
nicolas.grekas+php@gmail.com> wrote:Hello everyone,
as announced last week, I'm officially opening a discussion for adding a
"Stringable" interface to PHP 8.The RFC and its rationale are presented here as required:
https://wiki.php.net/rfc/stringableThe patch is found on GitHub, where some discussions happened already, you
might be interested in having a look:
https://github.com/php/php-src/pull/5083TL;DR, I think we need an interface to allow passing objects with a
__toString() method in a type-safe way, using the string|Stringable type.
Here is the stub of the proposal:
interface Stringable { public function __toString(): string; }I invite everyone to review the RFC before commenting here as I tried to
sum up considerations that some already had before and that you might have
too.Cheers,
NicolasI'm wondering whether it could make sense to automatically implement this
interface for all classes that define __toString(). Explicitly implementing
the interface is useful for the transition period (where old PHP versions
also need to be supported), but when considering only PHP 8 support, I
think it may make sense to implicitly implement the interface. If the
__toString() functionality also works fine without implementing the
interface, and there's probably only going to be relatively few consumers
of the Stringable type, it will likely be quite common that the interface
will not get implemented...Automatically implementing interfaces based on implemented methods could
also be a general language feature (see Go interfaces for example), but
likely not one we're interested in having in it's full generality. In this
particular case, it seems useful though.
This looks like a nice improvement to the proposal, it'd be OK on my side.
For the implementation, I might need your help to implement this logic,
especially for extensions, since I suppose we'd like them to also have this
behavior of implicitly declaring the return-type + interface when they
declare the method. Could you please help me achieve that?
Nicolas
On Wed, Jan 22, 2020 at 4:47 PM Nicolas Grekas nicolas.grekas+php@gmail.com
wrote:Hello everyone,
as announced last week, I'm officially opening a discussion for adding a
"Stringable" interface to PHP 8.The RFC and its rationale are presented here as required:
https://wiki.php.net/rfc/stringableThe patch is found on GitHub, where some discussions happened already, you
might be interested in having a look:
https://github.com/php/php-src/pull/5083TL;DR, I think we need an interface to allow passing objects with a
__toString() method in a type-safe way, using the string|Stringable type.
Here is the stub of the proposal:
interface Stringable { public function __toString(): string; }I invite everyone to review the RFC before commenting here as I tried to
sum up considerations that some already had before and that you might have
too.Cheers,
NicolasI'm wondering whether it could make sense to automatically implement this
interface for all classes that define __toString(). Explicitly implementing
the interface is useful for the transition period (where old PHP versions
also need to be supported), but when considering only PHP 8 support, I
think it may make sense to implicitly implement the interface. If the
__toString() functionality also works fine without implementing the
interface, and there's probably only going to be relatively few consumers
of the Stringable type, it will likely be quite common that the interface
will not get implemented...Automatically implementing interfaces based on implemented methods could
also be a general language feature (see Go interfaces for example), but
likely not one we're interested in having in it's full generality. In this
particular case, it seems useful though.Regards,
Nikita
I believe Anthony Ferrara proposed "Weak interfaces" once many years ago, which is essentially what you're describing. It didn't get much traction although I'm unclear why. (Possibly just less familiarity with Go at the time?)
I agree not all interfaces should be implicit, but having implicitly-implementable interfaces does sound generally useful. That shouldn't block this RFC, but might this RFC be a model for how to implement such things more generically in the future?
--Larry Garfield
Automatically implementing interfaces based on implemented methods could
also be a general language feature (see Go interfaces for example), but
likely not one we're interested in having in it's full generality. In this
particular case, it seems useful though.Regards,
NikitaI believe Anthony Ferrara proposed "Weak interfaces" once many years ago, which is essentially what you're describing. It didn't get much traction although I'm unclear why. (Possibly just less familiarity with Go at the time?)
I agree not all interfaces should be implicit, but having implicitly-implementable interfaces does sound generally useful. That shouldn't block this RFC, but might this RFC be a model for how to implement such things more generically in the future?
--Larry Garfield
Glad to see you picked up on this Larry.
I don't think "Weak Interfaces" became an RFC unless Google is failing me, but I found a reference to it being on the mailing list from Matthieu Napoli's article on GitHub about decoupling, which is worth a read:
https://github.com/mnapoli/mnapoli.github.io/blob/master/articles/decoupling-packages.md
As far as Go's implicit interfaces, I have found that to be one of the most compelling language features of Go, and would be ecstatic if we could find a way to support implicit interfaces in PHP.
-Mike
Le lun. 27 janv. 2020 à 10:19, Nikita Popov nikita.ppv@gmail.com a écrit :
On Wed, Jan 22, 2020 at 4:47 PM Nicolas Grekas <
nicolas.grekas+php@gmail.com> wrote:Hello everyone,
as announced last week, I'm officially opening a discussion for adding a
"Stringable" interface to PHP 8.The RFC and its rationale are presented here as required:
https://wiki.php.net/rfc/stringableThe patch is found on GitHub, where some discussions happened already, you
might be interested in having a look:
https://github.com/php/php-src/pull/5083TL;DR, I think we need an interface to allow passing objects with a
__toString() method in a type-safe way, using the string|Stringable type.
Here is the stub of the proposal:
interface Stringable { public function __toString(): string; }I invite everyone to review the RFC before commenting here as I tried to
sum up considerations that some already had before and that you might have
too.Cheers,
NicolasI'm wondering whether it could make sense to automatically implement this
interface for all classes that define __toString(). Explicitly implementing
the interface is useful for the transition period (where old PHP versions
also need to be supported), but when considering only PHP 8 support, I
think it may make sense to implicitly implement the interface. If the
__toString() functionality also works fine without implementing the
interface, and there's probably only going to be relatively few consumers
of the Stringable type, it will likely be quite common that the interface
will not get implemented...
This proposal has been implemented by Nikita himself on the linked PR, see
2nd commit:
https://github.com/php/php-src/pull/5083
I updated the RFC accordingly:
https://wiki.php.net/rfc/stringable
I think the RFC is ready for entering the voting stage.
Any other comments before?
Cheers,
Nicolas
On Tue, Feb 11, 2020 at 9:57 AM Nicolas Grekas nicolas.grekas+php@gmail.com
wrote:
Le lun. 27 janv. 2020 à 10:19, Nikita Popov nikita.ppv@gmail.com a
écrit :On Wed, Jan 22, 2020 at 4:47 PM Nicolas Grekas <
nicolas.grekas+php@gmail.com> wrote:Hello everyone,
as announced last week, I'm officially opening a discussion for adding a
"Stringable" interface to PHP 8.The RFC and its rationale are presented here as required:
https://wiki.php.net/rfc/stringableThe patch is found on GitHub, where some discussions happened already,
you
might be interested in having a look:
https://github.com/php/php-src/pull/5083TL;DR, I think we need an interface to allow passing objects with a
__toString() method in a type-safe way, using the string|Stringable
type.
Here is the stub of the proposal:
interface Stringable { public function __toString(): string; }I invite everyone to review the RFC before commenting here as I tried to
sum up considerations that some already had before and that you might
have
too.Cheers,
NicolasI'm wondering whether it could make sense to automatically implement this
interface for all classes that define __toString(). Explicitly
implementing
the interface is useful for the transition period (where old PHP versions
also need to be supported), but when considering only PHP 8 support, I
think it may make sense to implicitly implement the interface. If the
__toString() functionality also works fine without implementing the
interface, and there's probably only going to be relatively few consumers
of the Stringable type, it will likely be quite common that the interface
will not get implemented...This proposal has been implemented by Nikita himself on the linked PR, see
2nd commit:
https://github.com/php/php-src/pull/5083I updated the RFC accordingly:
https://wiki.php.net/rfc/stringableI think the RFC is ready for entering the voting stage.
Any other comments before?
Just so someone has mentioned it... is "Stringable" really the best name
for this interface? Reddit really didn't like it ;) Some possible
alternatives: ToString, HasToString, CastsToString.
Something to keep in mind is that there has been a recent proposal for
"Arrayable" as well, and that had very different semantics (not about
__toArray() at all).
Regards,
Nikita
Am 11.02.20 um 12:58 schrieb Nikita Popov:
Just so someone has mentioned it... is "Stringable" really the best name
for this interface? Reddit really didn't like it ;) Some possible
alternatives: ToString, HasToString, CastsToString.
I would vote for "Stringable" because PHP already has interfaces like
Throwable, Countable, Traversable, Serializable and so on :-)
Something to keep in mind is that there has been a recent proposal for
"Arrayable" as well, and that had very different semantics (not about
__toArray() at all).
I came up with the proposal of an Arrayable interface whose intention is
in fact very close to Stringable (can be used like an array and
converted to array vs. can be converted to string)
But time doesn't seem to be ripe for Arrayable because the __toArray()
RFC isn't accepted yet and there needs to be more discussion if
Arrayable should only contain __toArray() or if it should extend from
Countable and Traversable too.
Just so someone has mentioned it... is "Stringable" really the best name
for this interface? Reddit really didn't like it ;) Some possible
alternatives: ToString, HasToString, CastsToString.
Naming things...
I'm not sure reddit is the way to lobby php-internals...
I proposed Stringable because it is the most consistent to me:
Traversable, Serializable, Countable, Throwable, JsonSerializable
all are related to some special engine behavior, which this ones also is.
I'm on the side of keeping Stringable.
Something to keep in mind is that there has been a recent proposal for
"Arrayable" as well, and that had very different semantics (not about
__toArray() at all)
I didn't take part on this discussion, but I'm totally on Marco's side on
this one, I really hope this will NOT make it into the engine, for the
reasons he gives... :)
Nicolas
On Tue, Feb 11, 2020 at 1:12 PM Nicolas Grekas
nicolas.grekas+php@gmail.com wrote:
Just so someone has mentioned it... is "Stringable" really the best name
for this interface? Reddit really didn't like it ;) Some possible
alternatives: ToString, HasToString, CastsToString.Naming things...
I'm not sure reddit is the way to lobby php-internals...
I proposed Stringable because it is the most consistent to me:
Traversable, Serializable, Countable, Throwable, JsonSerializable
all are related to some special engine behavior, which this ones also is.
But one could argue that "string" is not a verb like "traverse",
"serialize", "count", "throw" etc.
Potential alternatives would be Stringifyable (or Stringifiable?),
StringCastable, StringConvertible...
(Even though I personally have no problem with "Stringable")
--
Guilliam Xavier
wt., 11 lut 2020 o 13:59 Guilliam Xavier guilliam.xavier@gmail.com
napisał(a):
On Tue, Feb 11, 2020 at 1:12 PM Nicolas Grekas
nicolas.grekas+php@gmail.com wrote:Just so someone has mentioned it... is "Stringable" really the best
name
for this interface? Reddit really didn't like it ;) Some possible
alternatives: ToString, HasToString, CastsToString.Naming things...
I'm not sure reddit is the way to lobby php-internals...
I proposed Stringable because it is the most consistent to me:
Traversable, Serializable, Countable, Throwable, JsonSerializable
all are related to some special engine behavior, which this ones also is.But one could argue that "string" is not a verb like "traverse",
"serialize", "count", "throw" etc.
Potential alternatives would be Stringifyable (or Stringifiable?),
StringCastable, StringConvertible...
(Even though I personally have no problem with "Stringable")
Maybe StringObject? We do already have ArrayObject.
BR,
Michał Brzuchalski
On Tue, Feb 11, 2020 at 2:11 PM Michał Brzuchalski
michal.brzuchalski@gmail.com wrote:
wt., 11 lut 2020 o 13:59 Guilliam Xavier guilliam.xavier@gmail.com napisał(a):
On Tue, Feb 11, 2020 at 1:12 PM Nicolas Grekas
nicolas.grekas+php@gmail.com wrote:Just so someone has mentioned it... is "Stringable" really the best name
for this interface? Reddit really didn't like it ;) Some possible
alternatives: ToString, HasToString, CastsToString.Naming things...
I'm not sure reddit is the way to lobby php-internals...
I proposed Stringable because it is the most consistent to me:
Traversable, Serializable, Countable, Throwable, JsonSerializable
all are related to some special engine behavior, which this ones also is.But one could argue that "string" is not a verb like "traverse",
"serialize", "count", "throw" etc.
Potential alternatives would be Stringifyable (or Stringifiable?),
StringCastable, StringConvertible...
(Even though I personally have no problem with "Stringable")Maybe StringObject? We do already have ArrayObject.
But ArrayObject is not a interface (ArrayAccess is).
--
Guilliam Xavier
Am 11.02.20 um 14:11 schrieb Michał Brzuchalski:
Traversable, Serializable, Countable, Throwable, JsonSerializable
all are related to some special engine behavior, which this ones also is.But one could argue that "string" is not a verb like "traverse",
"serialize", "count", "throw" etc.
Potential alternatives would be Stringifyable (or Stringifiable?),
StringCastable, StringConvertible...
(Even though I personally have no problem with "Stringable")Maybe StringObject? We do already have ArrayObject.
A StringObject would need to offer the same methods that are available
for strings (even if ArrayObject doesn't do that completely).
Even if "string" isn't a verb, it matches the intended meaning:
serialize -> Serializeable -> can be serialized
count -> Countable -> can be counted
throw -> Throwable -> can be thrown
If I take the alternatives into account, I would still opt for
"Stringable" because it's:
- easy to spell
- easy to remember
- shorter than the alternatives
- matches exactly the intended meaning
- consistent with the other PHP class nameings