Hi Jorg,

Apologies for missing your first message, It slipped past me.

The problem is typing a value whose valid set is a few specific primitives
you don't own and shouldn't model nominally: a flag that comes back as the
int 1, 2 or 3 from a database or C extension, an HTTP status, or an
'asc'|'desc' that exists only at one API boundary. Enums fit when you own
the type and want a named domain model with backing and methods. They're a
poor fit when the values originate outside your control, or when you need a
structural building block rather than a new named type, because an enum
then forces you to define, import and convert to and from a nominal type
for what is only "one of these primitive values." Enums stay the right tool
for domain modelling; this covers the cases they handle badly, the way
`int` and an `Age` value object coexist.

> I would prefer type aliases, such as Robert’s proposal from last year, as
a foundation before considering this direction:
https://wiki.php.net/rfc/typed-aliases

I'd love type aliases too, but they're orthogonal, and for the case you
care about they build on this feature. An alias names a type that must
already be expressible: `type Direction = 'asc'|'desc'` requires
`'asc'|'desc'` to be a valid type first. So literal types are the
prerequisite for aliasing the very `'asc'|'desc'` you'd want to name.

> This is exactly my concern. Literal types are useful in TypeScript, but
they are also often directly overused. I do not think PHP should encourage
the same pattern.
> My concern is that the RFC encourages public APIs like function f(1|2|3
$x) or function sort('asc'|'desc' $direction), where magic scalar values
become part of the runtime API instead of being represented by a properly
domain modeled entity.

A tool existing doesn't mandate its misuse. Enums remain available and are
still the recommendation for domain modelling; nothing here changes that.
Reaching a genuinely expressive type system means considering many
features: generics, literals, array shapes, typed arrays, aliases, ranges,
and more, most of which developers already rely on today through PHPDoc and
static analysers because they add value. We can't land them in one massive
overhaul; each needs its own focused discussion, and several (negated
types, conditional types) would look out of place in PHP on their own.
Literals are one of the foundational pieces the rest build on.

> Modern AI-assisted engineering makes semantic naming even more important.
Inline literal types such as 1|2|3 or 'asc'|'desc' provide less semantic
signal than named concepts such as enums or type aliases. This can make
code harder not only for humans, but also for AI tools that rely heavily on
names and surrounding context. However, I'm aware that this secondary
argument is not very plausible in this group.

I'm not sure about this. `function move('up'|'down'|'left'|'right' $d)`
states its valid inputs right at the signature. `function move(Direction
$d)` requires resolving what `Direction` is, class, interface or enum, and
what it permits, and how to obtain an instance of it before you do
anything. The literal form arguably carries more local signal, for a human
or an AI.

> Language features should be evaluated from the long-term user and
API-design perspective, not only from the static-analysis perspective. From
that perspective, I think this RFC approaches the problem from the wrong
side.

Agreed, and that's the motivation here. The feature is API-design driven,
with the future scope spelling it out: array shapes, integer ranges and
similar build directly on literal types as their foundation. That's the
long-term type-system frame I'd like the RFC judged on, rather than viewing
it as a static-analysis convenience.

Cheers,
Seifeddine

Reply via email to