> To the original question, there's two reasons that __toString() was 
> deliberately omitted from enums:
>
> 1. To discourage their use as "fancy strings". Enums are their own type, 
> independent of any other. Making them usable as 95% strings partially defeats 
> their purpose.

I disagree with the idea that we need to take this extreme of a stance when it 
comes to the notion of protecting the developer from themselves. There are a 
lot of really value use cases where it makes sense to have a string-backed enum 
. Not allowing developers to cast it to a string isn't doing anything but 
making people type $enum->value instead of (string)$enum -- so if someone wants 
to defeat their purpose this isn't stopping them. It is, however, making the 
language inconsistent because I literally have a enumeration defined by strings 
and there is literally no way to make PHP treat it like a string. This makes 
APIs sloppy imo because consider something like this:
function foo(string|Stringable $bar) {}
Because of these limitations this blows up into a much uglier thing in order 
accomplish what IMO should be a straightforward task:
function fooThatWantsString(string|Stringable|UnitEnum $bar)
{
if(($bar instanceof UnitEnum) && !is_string($bar->value)) {
throw InvalidArgumentException('This is exactly the sort of thing we are trying 
to get rid of with type hinting');
} else {
$bar = $bar->value;
}

$bar = (string)$bar;
}

Of course, you could also pass $bar->value higher up the call stack but it's 
much cleaner IMO to let the function call be smart enough to typecast as 
necessary. What's the point of a Stringable interface if we can't actually 
implement __toString() for it? Note again we can implement JsonSerializable and 
nothing complains when enum serializes to a simple string.
> 2. We still intend to add associated values to enums at some point (aka ADTs, 
> aka tagged unions), and... we're not really sure yet if that will impact 
> __toString() at all. It may, it may not, we don't know. So for now we're 
> keeping our options open by disallowing __toString(), in case it ends up 
> being needed for some ADT-related behavior in the future.
__toString() should return a string, if an enum literally represents a string 
constant it makes zero sense for it to ever return anything but that string 
constant. I don't think this is something ADTs or tagged unions or anything of 
the sort should play a role in deciding.
John

Reply via email to