Intersection types are very useful if you use composition over inheritance.
That is, in PHP, they are most useful when you are using multiple
interfaces and/or traits to represent different aspects of an object which
might be present. For example, using an actual library I maintain, I have a
concept of different number type objects.

NumberInterface - Anything that represents a cardinal number of any kind
will share this.
SimpleNumberInterface - Anything that represents a non-complex number will
share this.
DecimalInterface - Anything that is represented as a float/decimal will
share this.
FractionInterface - Anything that is represented with a numerator and
denominator will share this.
ComplexNumberInterface - Anything that has a non-zero real part and a
non-zero imaginary part will share this.

To correctly represent the return types for, say, the add() method on
Decimal, what I would *actually* return is something like
NumberInterface&SimpleNumberInterface&DecimalInterface. The add() method on
Fraction would instead return
NumberInterface&SimpleNumberInterface&FractionInterface.

Now, internally, the add() method has a check for whether there is an xor
relationship between real and imaginary parts of the two numbers. If there
is, then a complex number object is returned instead. This means that to
fully describe the return type of this function, the type would look like
this:

function add(NumberInterface $num): NumberInterface&(
(SimpleNumberInterface&DecimalInterface) |
(SimpleNumberInterface&FractionInterface) | ComplexNumberInterface)

It can return any combination of these depending on the combination of
types provided as arguments and being called. Now, if I got to just dictate
how this was implemented from my own userland perspective, I'd provide
typedefs and limit combination types to those. So, my ideal implementation
would like like:

typedef DecimalType =
NumberInterface&SimpleNumberInterface&DecimalInterface;
typedef FractionType =
NumberInterface&SimpleNumberInterface&FractionInterface;
typedef ComplexType = NumberInterface&ComplexNumberInterface;

function add(DecimalType|FractionType|ComplexType $num):
DecimalType|FractionType|ComplexType

But as I've mentioned earlier, none of this is really affected by
nullability. To me, that adds very little (though not nothing). Since it
accepts class types instead of classes themselves, I'd make an
OptionalInterface that provides the tools to return a null instance that
has useful information for the user of my library about why the object is
"null".

Full combination types between unions and intersections is something that I
would use heavily, but to me that means it should be implemented carefully
and thoughtfully.

As they are currently, I would use intersection types less often, but they
will still be useful in typed arguments.

I can provide actual github references to the code of mine that would
change if that would be helpful, but I wanted to provide a broad example of
how intersection types in general might be useful and how they might be
used.

Jordan

On Tue, Jul 27, 2021 at 6:14 PM Pierre Joye <pierre....@gmail.com> wrote:

> Good morning,
>
> On Wed, Jul 28, 2021 at 5:52 AM Rowan Tommins <rowan.coll...@gmail.com>
> wrote:
> >
> > On 27 July 2021 21:29:47 BST, "André Hänsel" <an...@webkr.de> wrote:
> > >> In fact, when 7.1 was released, none of the signatures changed in my
> > >code, they were just
> > >> updated to a different syntax.
> > >
> > >That by the way is only because of a specific compatibility behavior
> > >which is so confusing
> > >that I erroneously reported it as a bug:
> > >https://bugs.php.net/bug.php?id=80948
> >
> >
> > I can see how it would be confusing if you're coming to PHP fresh in the
> last few years, but from version 5.1 though to version 7.0, that was the
> way you marked nullable parameter types.
> >
> > It's a "compatibility behavior" only in the sense that it wasn't
> immediately removed when the more flexible "?type" syntax was added in 7.1.
>
> I get the feeling the nullable type syntax was not very well noticed
> by users when it came out. However it is not what is confusing I
> think. intersection, types on the other hand, are. I have yet to find
> usages so critical that we had to rush that in in an incomplete
> manner. I personally prefer how it is done in typescript, but same
> thought, I have yet to see good code design using them. ;)
>
> Best,
> --
> Pierre
>
> @pierrejoye | http://www.libgd.org
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
>
>

Reply via email to