Hi Deleu

> From Rob's email (https://externals.io/message/120094#120097), the argument
> against a simple "use" statement seems quite natural. I certainly don't
> want to redefine "use int|float as Number" in every PHP file I work with,
> so naturally we would go back to type alias definition, symbol registration
> and autoloading. So I guess my final question is: what is fundamentally
> different about Type Alias when compared to interfaces, classes, enums that
> make this controversial?

I don't think autoloading is the fundamental issue with type aliases,
nor are the symbol tables. Enums live in the class symbol table, as
they are just classes. Type aliases don't need most things classes
need, but they could live there too with a discriminator flag if we're
ready to waste that space for "convenience" of not rewriting all
accesses to the class table.

I believe the bigger issue is typing itself. There are multiple complications.

* Currently, any name that is not a known named type is considered a
class type. With type aliases this assumption is no longer correct,
which may require many changes in the engine (and in the optimizer).
* Combinations of union and intersection types are limited at the
moment (Foo|Bar, Foo&Bar, (Foo&Bar)|Baz). With type aliases we can
nest types indirectly to create new combinations that were previously
disallowed on a syntax level. We'll either have to handle these
correctly (which from what I understand is quite complicated) or
disallow them at runtime.
* Type variance may be challenging. E.g. do we allow substituting a
type alias with its concrete types and vice versa? What about
substituting two equivalent typealiases? There are infinite
* For runtime type checking itself we would need to compare the value
against the concrete types instead of the typealias, thus complicating
and slowing down the type check.

All of those could be solved (to some extent) by substituting the
typealias with the concrete types as early as possible and reusing the
existing type system. This is the approach I've tried some years ago:

The main issue with this approach is that classes/functions are
generally immutable (with OPcache) because we want to store them in
shared memory where all processes can access them. We have mechanisms
to make *parts* of the class/function mutable per request but
adjusting this for all types might once again require many code
changes. Furthermore, every type (with a typealias, at least) would
require copying to process space to substitute the typealiases with
the concrete type, for every request. This might or might not be
significant, it's hard to tell without measuring.

But the main reason why I stopped working on this was, what do we use
it for? Right now the main use cases are union and intersection types
which are fairly limited or short in my personal PHP code. A
reasonable use case might be closure types. However, I have become
increasingly sceptical whether runtime types for closures are the
direction we should take, as 1. they may be slow, hard to implement or
both and 2. most code doesn't *want* to add closures types that could
be inferred in most other typed languages.

This e-mail is not too structured and not exhaustive, let me know if
you have any more questions.


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

Reply via email to