Re: [RFC] [Discussion] Literal Scalar Types

From: Date: Sat, 04 Jul 2026 20:25:59 +0000
Subject: Re: [RFC] [Discussion] Literal Scalar Types
References: 1 2  Groups: php.internals 
Request: Send a blank email to internals+get-131767@lists.php.net to get a copy of this message
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 } ``` > 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. > 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. > 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()]]; } } ``` Cheers, Seifeddine.

« previous php.internals (#131767) next »