> Just to show the range of viewpoints on this, I'd like to mention my opinion > that Stringable is a horrible feature, with an implementation that's > completely inconsistent with the rest of the language, and no clear semantic > purpose. If your contract is "the input must be usable as a string", then the > obvious type to require is "string". > I'm not saying my opinion is objectively right, or even held by a majority, I > just wanted to provide a counterbalance of sorts.
I don't think it's without purpose... what it should be for is to allow developers to make flexible APIs where they can type-hint string|Stringable and the user of the API doesn't have to worry about it. There are examples where complex data types (object, enums) can be intelligently and reasonably cast to a string for more than simply "output" purposes (e.g. print statements, log files and the like). Since we have __toString() it makes sense to me to have an interface I can type against to know that method is valid to call instead of hunting around for it with method_exists() or other some such thing. See below for an example I pulled off the top of my head with an ORM. > >function fooThatWantsString(string|Stringable|UnitEnum $bar) > I would have thought the more common use case would be the opposite: you want > the function to be limited to a particular enum, but allow strings for > backward compatibility, and have this: > function fooThatTakesAnOption(FooOptionEnum|string $opt) { > if ( is_string($opt) ) { > $opt = FooOptionEnum::from($opt); > } > ... > } I think there's pretty meaningful evidence based on the engagement in the PR (and the number of likes in that PR regarding specifically at least allowing __toString() to be implemented) that your version of the mock API above and my version don't have to be mutually exclusive things -- nor is one vs. the other better or worse from a generic perspective. A composer package you pull into your project won't know the Enum type you want to pass in, but it shouldn't be hard for you to pass in a string enum if the API requires a string. There are plenty of APIs out there in the wild right now buried in various composer packages that expect a string but a string-backed enum might make sense.... I haven't tested this directly but just as an offhand example consider something like Laravel's Eloquent ORM: $model->query()->where('enumColumn', '=', MyEnum::MYVALUE)->get(); It's possible that Laravel has already been smart enough to add the necessary logic to look for UnitEnum here and resolve that to MyEnum::MYVALUE->value , but my argument is that it shouldn't have to try that hard. Nor should I have to write MyEnum::MYVALUE->value in my query -- nor should any developer ever have to think/worry about that for a string enum with a string parameter. As a library developer when I write a method to be used by others in an entirely unknown context, if my method takes a string input then I should be able to hint string|Stringable and know I've given users of my library maximum flexibility with basically no real effort on my part (other than a redundant $foo = (string)$foo line. The fact this works 99% of the time (except, strangely, string-backed enums) is the inconsistency I want to repair here. As it seems to me there isn't a particularly strong argument for why we don't allow __toString() , would anyone have a strong objection to getting an RFC going to get this voted on? I didn't look closely at the original PR from the "auto implement __toString()" for string-backed enums, but I think this might literally be a one-liner just to enable enums to implement __toString() and the rest can be tossed. John