Re: [PHP-DEV] [RFC] [Discussion] Literal Scalar Types

[email protected] (Nick Sdot) Sun, 5 Jul 2026 10:18:22 +0700
Newsgroups php.internals
Message-ID <[email protected]>
Het Seifeddine,

On 05.07.26 03:25, Seifeddine Gmati wrote:
> Hi Nick,
>
> Thanks for the feedback.
>
> > 1) if I did not miss anything the empty string case is not covered.
> > Would `""` be legal? Any thoughts on providing ways to explicitly
> > disallow empty strings? I don't think this should be further scope --
> > because we would need to make sure that we actually have a usable syntax
> > to disallow empty strings.
>
> Empty strings are supported; "" is a valid literal string type. 
> Regarding non-empty-string, that is a separate concept from literal 
> types. However, this RFC provides the building blocks to express it in 
> the future, through negated types (e.g., !""). There's also the option 
> of doing refinement markers on base types (e.g., string[1..]), which 
> IIRC Gina is working on or mentioned it somewhere.
>
> Example ( using literal types, negated types, and type aliases ):
>
> ```php
> type NonEmptyString = ! "";
>
> function getNonEmptyString(): NonEmptyString {
>   return 'ok'; // ok
>   return ''; // err
> }
> ```


Sounds good, thanks. Would be great if this would be spelled out in the RFC.

> > 2) having strict and non-strict mode in PHP is bad enough, IMO. Seeing
> > this brought further, and combined with "literal" (literal should be
> > literal) feels wrong -- a coerced `true` is de facto not a literal 1,
> > it's a coerced `true`. I understand that you recommend strict and want
> > to leave it to a vote, but I feel like the "Coercive matching
> > (alternative)" section should make a stronger point against it, to
> > discourage a tempting "always been like that" for a new concept.
>
> The RFC highlights that strict matching is already the established 
> behavior for existing value-types in PHP, and is the preferred path. 
> true, false, and null never coerce, even in coercive mode. Maintaining 
> this for all literal types is the only way to ensure a consistent type 
> system where a unit type matches exactly its identity, hence it is the 
> preferred option.

I believe we speak past each other here. With you that it should be 
strict matching, which you also prefer! I am just asking to make the 
"Coercive matching (alternative)" section more explicitly spell out why 
it isn't a good choice. As in: literal types would be a new feature for 
PHP, why would we apply and carry over lose semantics to something 
that's called "literal"? Not sure if I express myself good enough here, 
get what I mean? In short: make a stronger point for strict!

> > 3) the performance section is thin; solely addressing what Tim brought
> > up. I am wondering, does introducing this have any implications for
> > non-literal types? Having a benchmark would be nice. I also agree with
> > Jorg, that a benchmark comparing the performance with enums (memory +
> > speed) would be helpful.
>
> This proposal has no performance impact on non-literal type checks. 
> Comparing it to enums isn't quite apples-to-apples; enums are objects 
> and follow standard object comparison logic, whereas these are scalar 
> identity checks.


Maybe a benchmark would make a strong point for your proposal? Maybe 
better performance? Likely mess memory usage?

> > 4) the last part of the previous point extends to the general usefulness
> > of the feature. I again have to agree with Jorg: it is not clear what
> > problem it is trying to solve. Why not enums? It is a trend to get rid
> > of stringy APIs, and magic strings and ints -- for reasons. But this
> > feature will encourage bringing them back. With an enum you define it in
> > one place (easier to refactor), with literal scalar types you repeat it
> > in multiple places. Do we really want that?
>
> The core goal is to expand the type system to allow for more precise 
> descriptions of data. While literal types can be used standalone, they 
> are fundamental for future features like array shapes, where keys and 
> values often need to be narrowed to specific literals (e.g., a status 
> key being exactly 'ok' | 'error'). A richer type system, similar to 
> what we see in TypeScript, requires literals as a foundational 
> building block.
>
> Example ( using literal types, type aliases, array shapes, and integer 
> ranges ):
>
> ```php
> type ActionResponse = ['status' => 'ok' | 'error', 'message' => 
> string, ?'data' => array];
>
> interface Action {
>   public function perform(Context $ctx, Request $request): ActionResponse;
> }
>
> type PingActionResponse = ['status' => 'ok', 'message' => 'pong', 
> 'data' => ['time' => 0..]];
>
> final readonly class PingAction extends Action {
>   public function perform(Context $ctx, Request $request): 
> PingActionResponse {
>     return ['status' => 'ok', 'message' => 'pong', 'data' => ['time' 
> => get_time()]];
>   }
> }
> ```

Well, I believe you know my opinion here, and that we have fundamentally 
different ones -- which is fine. Before we bake anything more types into 
the language we should standardise PHPDoc, make an official spec. We got 
so many things wrong over the recent years that it would be the more 
sensible approach. And then the question remains, should we even inline 
types? Or is PHPDoc just great with some improvements and official 
acknowledgement?

Not sure if potential future language features, that might never come, 
are a good selling point that make an argument for getting literal types 
in now.

RE type aliases specifically... Something like: "we need to inline types 
to have them right where they are used, but then we want to have type 
aliases to move them away elsewhere right after" does make zero sense to 
me. How does both fit in the very same argument?

Some years ago I wrote the following somewhere (a "thing" refers to an 
"object"):

> This is one of the reasons I don’t like TypeScript. They put type 
> definitions everywhere.
>
> My thinking:
> An email is a thing. By having that thing we can describe it, with a 
> type. In real life, something that doesn’t exist, can’t have a type.
>
> So why would we do it differently in programming?
>
> A dedicated file/class for each thing is imho better. Eventually, the 
> thing is the type by itself. Because if you need the type, you need 
> the thing.
>
> What would be cool, is to have a type standard library so that not 
> everyone must write it on their own.

Just TypeScript having all these things doesn't mean that they are good 
for PHP. We should not make PHP another TypeScript.
>
> Cheers,
> Seifeddine.

--

Cheers
Nick