Re: [RFC] [Discussion] Literal Scalar Types
| From: | Seifeddine Gmati | Date: | Mon, 15 Jun 2026 22:37:23 +0000 |
| Subject: | Re: [RFC] [Discussion] Literal Scalar Types | ||
| References: | 1 2 3 4 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-131305@lists.php.net to get a copy of this message | ||
On Mon, 15 Jun 2026 at 21:32, Tim Düsterhus <tim@bastelstu.be> wrote:
>
> Hi
>
> On 6/15/26 21:45, Seifeddine Gmati wrote:
> > For what it is worth, I am personally fine with
tenths(0.1 +
> > 0.2)
> > failing to match 0.3. This is not new behaviour: QM=©
> > ÅᩞÛÌÖ0.1 + 0.2 == 0.3
> > is already false, and a match (0.1 + 0.2) already skips a
> > 0.3 arm
> > for exactly the same reason. So a literal float type behaves
> > consistently with comparison and match, rather than
> > introducing a
> > new surprise.
>
> Yes, it is consistent with the existing behavior, but I don't think that
> this makes it any less confusing. And for this specific proposal, adding
> support for floats would be a deliberate decision rather than just
> something that naturally follows from “existing === semantics” as with
> match() which works on two values rather than values + types.
>
> > On your concrete questions: 4e3 is a valid float literal
> > and works
> > today; it normalizes to 4000.0 (the type also stringifies
> > as
> > 4000.0). NAN and
> > INF, on the other hand, are not literals but
> > constant identifiers that go through constant resolution. They are out
> > of scope for the same reason FOO is above:
> > NAN $foo could just as
> > well mean a class named NAN.
>
> Yes, I'm aware (based on a look at the implementation). This was
> intended to be a subtle note that this is not explicitly spelled out in
> the RFC.
>
> The RFC text should comprehensively explain the behavior all possible
> edge cases and ambiguities so that folks can form an educated opinion
> based on the RFC text alone without needing to be able to understand the
> implementation.
>
> Writing that out, I also notice that the “Ecosystem” sub-section is
> missing from the “RFC Impact” section (and the “To Existing Extensions
> ” sub-subsection would probably also be useful to know) and the voting
> widget is also missing.
>
> Best regards
> Tim Düsterhus
Hi Tim,
That is fair. Float support should be a deliberate choice rather than
something that rides in on existing === semantics; the match
analogy only goes so far, since match compares two values whereas
this compares a value against a type.
You are also right that the RFC text has to stand on its own. I will
expand it to spell out the edge cases explicitly, including:
- Which numeric forms are accepted and how they normalize.
Hexadecimal, octal, binary and underscore-separated integer literals
(0x1A, 0o17, 0b101, 1_000) all canonicalize to
their value,
and 4e3 is a valid float literal normalizing to 4000.0.
- That NAN and INF are constants, not literals, and so are not
accepted, for the same reason a bare FOO is not.
- String literal handling: single versus double quotes, escape
resolution, and the rejection of interpolation.
I will also add the missing "Ecosystem" and "To Existing Extensions"
subsections under "RFC Impact", and the voting widget.
On voting: rather than a single yes/no, would it make sense to split
it so each decision can stand on its own?
1. Add support for literal string types. (2/3)
2. Add support for literal integer types. (2/3)
3. Add support for literal float types. (2/3)
4. Coercion behaviour: coerce to the base type before checking
membership (as the RFC currently describes), or always require an
identity match. (1/2)
The last one is worth surfacing in particular. true, false and
null do not coerce at all today, even in coercive mode: passing 1
to a true parameter is a TypeError, not a coercion to true.
If
we want literal scalars to be consistent with the existing value
types, an identity match is arguably the more natural behaviour, so I
would rather put it to the list than bake it in.
Best regards,
Seifeddine