On Mon, Jun 15, 2026 at 3:27 AM David Gebler <[email protected]> wrote:
> On Mon, Jun 15, 2026 at 3:13 AM Seifeddine Gmati <[email protected]> > wrote: > >> On Mon, 15 Jun 2026 at 03:03, David Gebler <[email protected]> wrote: >> > >> > On Mon, Jun 15, 2026 at 2:24 AM Seifeddine Gmati >> <[email protected]> wrote: >> >> >> >> Hello Internals, >> >> >> >> I'd like to start the discussion on a new RFC adding literal scalar >> >> types to PHP. >> > >> > >> > Prima facie, I feel like enums already do what this aims to achieve, >> much better. >> > >> >> >> >> >> >> - RFC: https://wiki.php.net/rfc/literal_scalar_types >> >> - Implementation: https://github.com/php/php-src/pull/22314 >> >> >> >> Thanks, >> >> Seifeddine. >> >> Hi David, >> >> I agree enums are the better fit for a lot of cases. but not all. >> >> 1. describing APIs that already exist. `array_filter`'s `$mode` really >> accepts `0|1|2`, but it's typed `int` because that's all the type >> system can say today. we can't retype it as an enum without breaking >> every caller. a literal union lets the signature state the actual >> contract. >> > > This is probably the strongest case (and should be mentioned on the RFC, I > think), though I'm not sure it's a sufficient justification for the scope > of change. > > >> 2. ad-hoc / open value sets. for a library, "ascii"|"utf-8" would need >> its own named symbol ( `enum BorderStyle { case Ascii; case Utf8 }`, a >> new file, an import ) for what is really two strings. and because an >> enum is a closed set, adding a third style later breaks any consumer >> that match-es over it without a default. widening the union on a >> parameter ( "ascii"|"utf-8"|"unicode" ) is contravariant, so it breaks >> nobody. >> > > I'm not so convinced on this point. You add a new case to an enum, that > library's API isn't inherently broken. Users passing Ascii or Utf8 per the > original case-set remain valid. The only code that breaks there is code > that assumes the enum would never gain another case and the same could be > said of code matching on string literals without a default. And if > "ascii"|"utf-8" is what a library exposes, consumers may treat that as > exhaustive, whereas an enum doesn't inherently break as a type hint. A set > that's *expected* probably shouldn't be an enum, but the strength of an > enum is precisely that it's a (probably) closed set of values. On the > flip-side, if a set of values is genuinely open-ended, a closed set of > scalar literal unions as a type isn't going to help. > Apologies for typo of omission in the above paragraph, I meant to say "A set that's expected to grow probably shouldn't be an enum" > > > >> 3. scalar interop. a literal value is the scalar, so it works as an >> array key, compares with ===, round-trips through json, etc. enum >> cases are objects and don't. >> > > I think backed enums already cover this through value exposure. > > >> >> so they overlap a lot, but literal unions reach things enums >> structurally can't: existing scalar APIs, and open sets that grow >> without a BC break. >> >> Cheers, >> Seifeddine. >> >
