# [RFC] Add true as type

- Thread: https://externals.io/message/117500
- Original archive: https://news-web.php.net/php.internals/117500
- Started by G. P. B. on 2022-04-08T16:47:19+00:00
- Messages: 10
- RFC: Add true type (Implemented (PHP 8.2)) — https://externals.io/rfc/true-type.md
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · RFCs at https://externals.io/rfc.md · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #117500 — G. P. B. — 2022-04-08T16:47:19+00:00

URL: https://externals.io/message/117500#117500

Hello internals,

I would like to open the discussion on the RFC to add true as a type.
https://wiki.php.net/rfc/true-type

Now that null and false can be used as standalone types, I think it makes a
lot of sense to add true as a value type for the sake of completeness with
false.

It also has many use cases within internals and userland to declare proper
type signatures to functions and methods.

Best regards,

George P. Banyard

---

## #117504 — Björn Larsson via internals — 2022-04-08T21:39:39+00:00

URL: https://externals.io/message/117500#117504 · In reply to: #117500

Den 2022-04-08 kl. 18:47, skrev G. P. B.:
> Hello internals,
> 
> I would like to open the discussion on the RFC to add true as a type.
> https://wiki.php.net/rfc/true-type
> 
> Now that null and false can be used as standalone types, I think it makes a
> lot of sense to add true as a value type for the sake of completeness with
> false.
> 
> It also has many use cases within internals and userland to declare proper
> type signatures to functions and methods.
> 
> Best regards,
> 
> George P. Banyard
> 
Finally, I have been waiting for this :) Two comments:
- Would be nice to have an example / UC that shows the value of true as 
a type in the RFC.
- Should one have a link to the earlier discussion about this type, 
either in the RFC or in the announcement on the internals list?

Regards //Björn

---

## #117506 — tim@bastelstu.be — 2022-04-09T11:05:37+00:00

URL: https://externals.io/message/117500#117506 · In reply to: #117500

Hi


> Now that null and false can be used as standalone types, I think it makes a
> lot of sense to add true as a value type for the sake of completeness with
> false.

I agree that it would make sense to have 'true' as the counterpart of 
`false` for completeness, but …

> It also has many use cases within internals and userland to declare proper
> type signatures to functions and methods.
> 
… seeing the examples of functions that might return `true`, but won't 
return false, I feel like the correct solution is not adding `true` as a 
standalone type, but instead making those function return something more 
obvious.

- The `sort()` family should rather be be ': void' which would make it 
more obvious to static analysis that '$sorted = sort($unsorted)' is not 
a correct usage.
- `DiagnoseCommand::checkComposerSchema()` in composer would benefit 
from having support for tagged unions, as currently both the error case 
(`string`) and the success case (`true`) are truthy. With the current 
PHP 8.1 feature set I can imagine that returning a proper bool and 
putting the reason in an `string &$reason` reference parameter would 
make it more obvious to use this function in an `if ()`.
- `JsonFile::validateSchema()` in composer should be ': void' as errors 
appear to be communicated using Exceptions.
- The closure in `ComposerRepository::asyncFetchFile()` would benefit 
from having support for tagged unions, but even with the current PHP 8.1 
feature set I can imagine that:

     enum CacheStatus { case Hit; }

and then making the function `mixed[]|CacheStatus` instead of 
`mixed[]|true` would make it more obvious what the meaning of the second 
option in the union is.

Best regards
Tim Düsterhus

---

## #117511 — G. P. B. — 2022-04-11T13:32:58+00:00

URL: https://externals.io/message/117500#117511 · In reply to: #117506

> Hi
>
> 
> > […]
> makes a
> > […]
> with
> > […]
>
> I agree that it would make sense to have 'true' as the counterpart of
> `false` for completeness, but …
>
> > […]
> proper
> > […]
> … seeing the examples of functions that might return `true`, but won't
> return false, I feel like the correct solution is not adding `true` as a
> standalone type, but instead making those function return something more
> obvious.
>
> - The `sort()` family should rather be be ': void' which would make it
> more obvious to static analysis that '$sorted = sort($unsorted)' is not
> a correct usage.
> - `DiagnoseCommand::checkComposerSchema()` in composer would benefit
> from having support for tagged unions, as currently both the error case
> (`string`) and the success case (`true`) are truthy. With the current
> PHP 8.1 feature set I can imagine that returning a proper bool and
> putting the reason in an `string &$reason` reference parameter would
> make it more obvious to use this function in an `if ()`.
> - `JsonFile::validateSchema()` in composer should be ': void' as errors
> appear to be communicated using Exceptions.
> - The closure in `ComposerRepository::asyncFetchFile()` would benefit
> from having support for tagged unions, but even with the current PHP 8.1
> feature set I can imagine that:
>
>      enum CacheStatus { case Hit; }
>
> and then making the function `mixed[]|CacheStatus` instead of
> `mixed[]|true` would make it more obvious what the meaning of the second
> option in the union is.
>
> Best regards
> Tim Düsterhus
>

There are many many many more internal functions in PHP which only return
true, but only since PHP 8.0.0, and this is due to the huge amount of
 `E_WARNING` to ValueError/TypeError promotion which has happened.
These functions previously did return false in certain circumstances, and
although I agree that changing these to void *would* be the most ideal,
being able to do this communicating that these functions only return true
(which means one can ignore the return value) is the first step.
Moreover, it is even more of a BC break compared to changing something
which only returns false to void as code like:
if (always_true(...)){ ... }
would stop executing this code path.

Not adding true as a type prevents extending methods which return bool to
always return true to clearly document this within the typesystem.

Best regards,

George P. Banyard

---

## #117512 — Guilliam Xavier — 2022-04-11T13:45:15+00:00

URL: https://externals.io/message/117500#117512 · In reply to: #117511

Hi,



>
> There are many many many more internal functions in PHP which only return
> true, but only since PHP 8.0.0, and this is due to the huge amount of
> `E_WARNING` to ValueError/TypeError promotion which has happened.
> These functions previously did return false in certain circumstances, and
> although I agree that changing these to void *would* be the most ideal,
> being able to do this communicating that these functions only return true
> (which means one can ignore the return value) is the first step.
> Moreover, it is even more of a BC break compared to changing something
> which only returns false to void as code like:
> if (always_true(...)){ ... }
> would stop executing this code path.
>
> Not adding true as a type prevents extending methods which return bool to
> always return true to clearly document this within the typesystem.
>

Then you should probably update the RFC to say that, and better examples ;)
Maybe also add an example of "refinement" during inheritance (from `: bool`
to `: true`)?

One more thing: maybe the part about `true|false` being an error (use
`bool`) should be its own subsection, as that's not exactly "redundancy",
and differs from `array|\Traversable` being interchangeable with `iterable`.

Regards,

-- 
Guilliam Xavier

---

## #117513 — tim@bastelstu.be — 2022-04-11T13:59:45+00:00

URL: https://externals.io/message/117500#117513 · In reply to: #117511

Hi


> There are many many many more internal functions in PHP which only return
> true, but only since PHP 8.0.0, and this is due to the huge amount of
> `E_WARNING` to ValueError/TypeError promotion which has happened.
> These functions previously did return false in certain circumstances, and

I see. I think you should clarify this in the "Examples" section, that 
(some of) these functions previously were an actual `: bool` instead of 
`: true`.

> although I agree that changing these to void *would* be the most ideal,
> being able to do this communicating that these functions only return true
> (which means one can ignore the return value) is the first step.
> Moreover, it is even more of a BC break compared to changing something
> which only returns false to void as code like:
> if (always_true(...)){ ... }
> would stop executing this code path.

I was not attempting to argue that the return type should be changed to 
`: void` (because of the obvious BC issues). Instead I believe that 
probably would choose an entirely different return type if the functions 
would be newly introduced.

> Not adding true as a type prevents extending methods which return bool to
> always return true to clearly document this within the typesystem.

This argument was also used for allowing `null` / `false` as a 
standalone type, because there is no good reason to allow `null` / 
`false` in a union type, but not standalone.

For `true` the story is different, as this type is an entirely new type 
available to userland and by the same argument one could have literal 
strings or literal integers as distinct types as well. I wouldn't object 
to that per se (and there's precedent in TypeScript), but there could be 
a clearer plan for the type system as a whole, instead of adding types 
piecemeal.

I *can* see the value in having `true` for completeness, though.

Best regards
Tim Düsterhus

---

## #117516 — Sara Golemon — 2022-04-11T16:18:13+00:00

URL: https://externals.io/message/117500#117516 · In reply to: #117513

> For `true` the story is different, as this type is an entirely new type
> available to userland and by the same argument one could have literal
> strings or literal integers as distinct types as well. I wouldn't object
> to that per se (and there's precedent in TypeScript), but there could be
> a clearer plan for the type system as a whole, instead of adding types
> piecemeal.
>

^This. The bit about making a plan, I mean.  A slow erosion of what it
means to be a type might be the easier pill to swallow, but it results in
more chaos overall in the type system.  I'd like to see someone (literally
anyone) take the time to sketch out a more complete picture for the type
system.  We can implement it in pieces and parts, but we should have a goal
in mind for where we want to land.

Using this RFC as an example, it naturally leads into the question of value
types (which is what `true` really is, a bool with a value of true), so why
can't we say this method must return the number 42 or a string containing
'pamplemousse' ?  A roadmap would help us understand what those kinds of
value types (in an unbounded type like string or a large bounded type like
int) compared to the tight bounded type of bool.

And yes.  Generics.   We can't talk about the type system without the
subject of generics being extremely relevant.  Ignoring them because it's
complicated is just kicking the can down the road.

All that having been said, sure. I don't mind adding true for completeness,
because it's fairly obvious and the scope of bool is fairly small, but I
would really encourage anyone to step up and plan out a wider reaching goal
for the type system.

-Sara

---

## #117520 — Andreas Hennings — 2022-04-11T22:48:20+00:00

URL: https://externals.io/message/117500#117520 · In reply to: #117516

> sketch out a more complete picture for the type
system.  We can implement it in pieces and parts, but we should have a goal
in mind for where we want to land.

I think the type system in psalm is pretty cool. It does have fixed
literal values, but also deeply structured array types.
But:
- I don't think we'll arrive there in one leap
- I am not sure we _want_ to arrive there, ever. Perhaps it is just
too much for native support, especially if we want repeated runtime
checks.
- Runtime checks on array types seem like a nightmare.
- I am pretty confident that adding `true` won't close any doors fur
future type systems, if we already have `false`.

Alternatively we could look at compile-time type systems like in C++
(or Java?), where we don't have to waste time on runtime checks.
The default implicit variable type could be "variant", but variables
with a declared type would behave as in C++, with a faster and slimmer
storage model.
Of course any union type that allows values other than object or null
would have to use the storage model of "variant".
Sounds like a lot of work, but if we want to dream big, it is
something to consider.

(There might be better examples than C++, I only mention it because I
spent some time with it long ago. Perhaps even Java?)

-- Andreas


>
> 
> > […]
>
> ^This. The bit about making a plan, I mean.  A slow erosion of what it
> means to be a type might be the easier pill to swallow, but it results in
> more chaos overall in the type system.  I'd like to see someone (literally
> anyone) take the time to sketch out a more complete picture for the type
> system.  We can implement it in pieces and parts, but we should have a goal
> in mind for where we want to land.
>
> Using this RFC as an example, it naturally leads into the question of value
> types (which is what `true` really is, a bool with a value of true), so why
> can't we say this method must return the number 42 or a string containing
> 'pamplemousse' ?  A roadmap would help us understand what those kinds of
> value types (in an unbounded type like string or a large bounded type like
> int) compared to the tight bounded type of bool.
>
> And yes.  Generics.   We can't talk about the type system without the
> subject of generics being extremely relevant.  Ignoring them because it's
> complicated is just kicking the can down the road.
>
> All that having been said, sure. I don't mind adding true for completeness,
> because it's fairly obvious and the scope of bool is fairly small, but I
> would really encourage anyone to step up and plan out a wider reaching goal
> for the type system.
>
> -Sara

---

## #117550 — G. P. B. — 2022-04-20T16:30:13+00:00

URL: https://externals.io/message/117500#117550 · In reply to: #117520

Hello internals,

I've expanded on the RFC:
https://wiki.php.net/rfc/true-type

Please let me know if there are still aspects which need clarification.

I will also say that I think enums are far superior to literal types, but
only having false and not true is extremely weird to me (and in a pure type
theoretical perspective I would have preferred to not even have false).
The complexity of the implementation is also "trivial" because the PHP
engine already considers true and false to be two different ZVAL types,
whereas a complete literal type implementation is going to be way more
complex and I doubt be far from efficient.

Best regards,

George P. Banyard

---

## #117797 — G. P. B. — 2022-05-27T07:04:16+00:00

URL: https://externals.io/message/117500#117797 · In reply to: #117550

Hello internals,

I will open voting on this tomorrow unless further comments.
https://wiki.php.net/rfc/true-type

Best regards,

George P. Banyard
