> I want to bring your attention to a behavior that was mostly overlooked:
>>
>>    1. it is not possible to use an intersection type with an argument that
>>    defaults to null
>>    2. it is not possible to use an intersection type with a nullable
>>    property (nor to make it default to null)
>>    3. it is not possible to use an intersection type with a nullable
>> return
>>    type
>>
>> Actually, 2. was possible until it was "closed" in
>> https://github.com/php/php-src/pull/7254
>>
>> I reported these behavior and you might find some discussion about it in
>> https://bugs.php.net/81268
>>
>> Looking at the past discussion on this list (
>> https://externals.io/message/113712) and at the rfc itself (
>> https://wiki.php.net/rfc/pure-intersection-types), this was mostly
>> overlooked.
>>
>> That's why I'm posting this message. So that we can have that missing
>> discussion here.
>>
>> To me, we are going to need (userland "we") these capabilities.
>>
>> It's quite surprising to be "forced" to return something, or "forced" to
>> pass a value, when all other types in PHP allow "null". I know about the
>> null pattern, but it is quite uncommon in PHP, because "null" works just
>> great usually.
>>
>> I feel like we "just" need to agree on a syntax to make this possible. It
>> was first suggested in the related PR to use "?A&B" (see
>> https://github.com/php/php-src/pull/6799#issuecomment-804761117)
>>
>> This was rejected by the author with the reasoning that (?A)&B could mean
>> (?A)&B or ?(A&B) or even (?A)|B.
>>
>> I personally don't think this ambiguity exists: (?A)|B is strictly the
>> same
>> as A&B, thus ?A&B cannot also mean A&B, and I don't get how one could take
>> ?A&B for  (?A)|B.
>>
>
> To me, the `|` (instead of `&`) in the original "is it `(?A)|B` or
> `?(A&B)`" was just a blatant typo. By the way, I think you made a couple of
> typos yourself: [...]
>

You're right, sorry about that...

As for supporting the `?A&B` syntax, several issues were raised:
>   - Ambiguity: We would want the `?` "unary operator" to have a "lower
> precedence" than the `&` "binary operator" (like `null|A&B` or explicit
> `null|(A&B)`), which would be the opposite of familiar `!A&B` for "true"
> operators.  There was also some opposition to "implicit precedence" /
> preference for requiring explicit grouping.
>

As I wrote in my original message, I don't think this one holds: ?X&Y
cannot mean (?X)&Y because this is strictly and trivially equivalent to X&Y.


>   - Inconsistency: The similar `?A|B` syntax was explicitly rejected when
> introducing union types.  Moreover the future scope anticipates full
> composite types, allowing arbitrary `A&B|C` (or `(A&B)|C
>

The features we ship should be fully fledged. I don't know the future, and
nobody does.
Anyway, this doesn't prevent accepting ?X&Y since the syntax in your
example doesn't conflict.


> And the main obstacle to supporting general composite types (whatever the
> syntax): Unknown variance/LSP correctness (apparently complex to
> specify/implement): George expressed themself in
> https://wiki.php.net/rfc/pure-intersection-types#composite_types_ie_mixing_union_and_intersection_types
> :
>

Here is the PR, no need for suppositions. Please send me test cases about
those unknown and let's discover them if they need to.
https://github.com/php/php-src/pull/7259



> That said, to me it also feels like the `null` type/value is "special",
> and that PHP has a history of "nullability" being more than "just a union
> where one of the types is `null`", making "nullable intersection types"
> desirable (even without waiting for [hypothetical] full composite types).
>

Absolutely, null is special in the codebase, that's why the patch in the
linkedPR is trivial.

Thanks for your answer btw !

Nicolas

Reply via email to