> 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

Reply via email to