On Sat, 2 Oct 2021 at 16:37, tyson andre <tysonandre...@hotmail.com> wrote:
>
> Hi Andreas,
>
> > Hello list,
> > I would like to propose new methods for ReflectionType, that would
> > allow treating ReflectionNamedType and ReflectionUnionType in a
> > unified way.
> > This would eliminate the need for if (.. instanceof) in many use cases.
> >
> > Some details can still be discussed, e.g. whether 'null' should be
> > included in builtin type names, whether there should be a canonical
> > ordering of type names, whether we should use class names as array
> > keys, etc.
> > ...
> > What do you think?
>
> Relatedly, I also had different ideas lately about new methods for 
> ReflectionType, though of a different form.
>
> 1. To simplify code that would check `instanceof` for all current and future 
> types such as `never` and `mixed` and intersection types
>     `ReflectionType->allowsValue(mixed $value, bool $strict = true): bool`
>
>    Maybe also `allowsClass(string $className, bool $strict = true): bool` to 
> avoid needing to instantiate values (weak casting allows Stringable->string).

Ok for me, why not.
I would see it as a distinct PR, separate from my original proposal.
The problem or limitation of these methods is that they don't reflect
the full expressiveness of the type system.
That is, the return values of these methods would not be sufficient to
recreate an equivalent type.

> 2. To simplify code generation, e.g. in mocking libraries for unit testing: 
> `ReflectionType->toFullyQualifiedString(): string` (e.g. `\A|\B`) (may need 
> to throw ReflectionType for types that can't be resolved, e.g. `parent` in 
> reflection of traits, keep `static` as is)
>
>     (The raw output of `__toString()` isn't prefixed with `\` (e.g. `A&B`) 
> and can't be used in namespaces

Again, if we iron out the details, it can be a good idea as a distinct
standalone PR.

>
> The fact that both intersection and union types (and possibility of union 
> types of full intersection types)
> make it hard for me to believe that getBuiltinTypes and getBuiltinClasses 
> would be used correctly when used.

Just to mention it, my proposed names were getBuiltinNames() and
getClassNames() to be super clear that the return value will be
string[].

For future intersection types, there could be additional methods
getBuiltinIntersectionTypes() and getClassIntersectionTypes(), or it
would be a single method getIntersectionTypes(). Not sure yet which
combos make sense. E.g. array&callable would combine two builtin
types, Countable&callable would combine a class-like type and a
builtin type.
Every type would be broken into a normal form, where the top-level is
treated as a union type, and each item can either be a pure builtin
type, a pure class type, or an intersection of pure types.

int|string|(A&(B|(C&D))) === int | string | (A&B) | (A&C&D)

If we always use this normal form, then the ReflectionIntersectionType
only needs to have getBuiltinNames() and getClassNames(), not
getUnionTypes().

Not sure yet what to do with 'static' and '$this'.


>
> Thanks,
> Tyson
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
>

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php

Reply via email to