-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Brainstorming easier type inference #1
Comments
I think about DI containers in this context a lot, it's a meaningful use-case 👍 What I envisioned for my own DI container is something along the lines of this: class Container
{
public function get<T = mixed>(string $name = null): T
{
return $this->dependencies[$name ?? T::class];
}
// ...
}
// examples:
$service = $container->get<MyService>(); // singleton component
$pdo = $container->get<PDO>("connection_name"); // named component
$foo = $container->get("foo"); // named component, no type-check (T defaults to mixed) That is, you can optionally specify the component name statically with a type-argument, for singleton services, or you can specify the component name yourself to get a specific instance - or both, specify a component name as well as the expected type, for better static analysis plus run-time type-checking of the returned component. I'd like the type alias Default type-arguments are described in the spec, only (as noted in the spec as well) there's presently no way to type-hint as
It's definitely possible in this particular case - many things are type-hinted in PHP and doesn't trigger auto-loading, for example In summary, type-hints in PHP exist only as strings in-memory until the implementation of the type is required. It's really important that the implementation of generics sticks to that pattern as closely as possible. For example: function is_a<T>($value): bool {
return $value instanceof T;
}
$foo = new Foo();
var_dump(is_a<Bar>($foo)); // => false This should not trigger auto-loading of Similarly: use Foo\Bar;
function get_type<T>(): string {
return T::class;
}
var_dump(get_type<Bar>()); // => "Foo\Bar" This should also not trigger auto-loading of In both cases, all that is required is the name of the type, and not the implementation. |
🤦♀️ Yeah, The part about the lazy instantiation referred to I don't think we need a mixed type because a generic EDIT |
The See the
Yes, but how will you specify that "any" (in php-doc "mixed") as a default? That is, we need to support both optional and required type-arguments: function foo<T = mixed>() {} // optional type-argument
function foo<T>() {} // required type-argument The default for type-arguments should be required - specifying a default of The point is, type arguments need to always refer to a type - if they're optional, they must default to something. They can't be Note that there's already edge-cases in PHP, because scalar types like I think it's important we don't introduce yet another inconsistency here, so I don't think there's any sound way around adding a |
How would
Based on the RFC, I assume that it returns Default type parameter values Additionally, specifying a parameter as Do you have any strong reasons for why default values should be supported? |
I thought so early on while writing the RFC, but I think there are only rare and marginal use-cases for that - maybe as keys (for example in a registry or DI container) but probably not much else. There should be a way to get a string like Generating strings such as And we want to make sure that e.g.
Absolutely 👍
There's a subtle difference: "untyped" would imply that there's a I also think that However, disallowed It's an inconsistency of the language, but one that we have to deal with - so, where other languages have e.g. If we don't support something like If we don't allow something like
You mean default type-arguments? They're sometimes convenient, when you have a likely use-case for a generic class and you'd like to provide a default. In other words, this is primarily for convenience. (I write a lot of Typescript, and have found defaults to be useful from time to time.) I don't think there's any reason not to support this feature? You can read about some of the reasons people wanted this feature in Typescript here. |
Ok, thanks for your feedback! |
I've been trying to figure out how to create an easier way to provide type information to methods as an argument, similar to how Java can use
MyClass.class
to return aClass<T>
. This is basically the same as PHP'sReflectionClass
if you're unfamiliar.I don't necessarily want to start typing to
ReflectionClass<T>
or change the signature ofReflectionClass
, but that's an option.I'm not sure if it's possible, but it would be great if we could use a constant to return an instance of the required type, something like
MyClass::type
. I would definitely want that instantiation to be lazy, and I'm not sure if that's possible in PHP.Perhaps, there could be a new mini reflection class (e.g.
ClassToken<T>
) that could provide a minimal amount of information about the class signature (name, type parameters, etc).What this solves
A good example of what this could help with is a dependency container.
For example, a container could have this method:
We could still derive value from using generics:
But this is a little long. Ideally, we could do something like this instead:
MyDependency::type
would return aClassToken<MyDependency>
The text was updated successfully, but these errors were encountered: