Hi all, thanks for the valuable feedback! @Stephen Reay:
> I like the idea but I find the syntax (both suggestions) less than great, given that there’s already “ensure a type” syntax, and both suggestions are already used for other things (casting and foreach) Note that we already use `as` in other contexts than foreach: in imports (`use Foo as Bar`) and in traits (`use SomeTrait { foo as bar; }`) , so I think that reusing the keyword for yet another use case is OK, as long as it does not conflict. > Is there some reason (eg ambiguities) a type can’t just be placed before a variable to ensure a type, similar to a function parameter or typed property? > string $foo = 'bar'; > ... > I’m talking about exactly the same functionality that exists with method parameters - constraining the type it must conform to when it is declared. Nothing more nothing less. I would personnally read this as "this variable is now strongly typed, INCLUDING later assignments" (which would belong to another feature / discussion), but as you have later clarified that this is not what you had in mind, I think that this syntax is then even more confusing than the other proposals: Foo $foo = new Foo(); $foo = 123; // this would work? > Using `as` means trying to add type constraints to an iterable in the foreach would be ridiculously confusing: > foreach ( $foo as $K as int => $v as string) {...} Please note that my proposal is specific to class/interface names, not other types for now (I could consider broadening it if people are interested in the suggested "as" syntax from Hack). Anyway with the two syntaxes suggested so far, you would not inline it in the foreach, but explicitly write: foreach ($foos as $foo) { $foo = (Foo) $foo; // or $foo = $foo as Foo; } @Andreas Hennings: > If I remember correctly, an object pointer (object variable) in Java has a type independent of the object it points to. The pointer type restricts the range of object types that can be pointed to from the variable. > You can cast the pointer type (variable type) to let a variable of different object pointer type store the same object, as long as the type is compatible. > In PHP, variables have no type on language level, so casting would indeed be a misleading concept. Unless we want to change this. You have a point for sure, but as I said above, I don't feel like this makes it incompatible with casting semantics. In Java, casting to a class/interface name: 1. ensures that the variable holds an instance of this class/interface 2. changes the pointer type, which affects later usage of the object In PHP, you'd just scratch point #2 which is irrelevant. Is this a good enough reason to stop using the casting syntax? I'm not sure. @Sebastian Bergmann: > Today's equivalent is, at least for me, is this one-liner: > assert($service instanceof EmailService); Let's be picky: this is actually a two-liner, a second line after the variable declaration ;-) > This way the IDE knows what type $service is supposed to be and there will > be an exception at runtime (given the appropriate configuration) when this > is not the case. That's a fair point regarding the IDE. The exception at runtime however, becomes strongly dependent on PHP configuration. We're also losing the advantage of an explicit language construct, that I suspect could be later used by the JIT compiler to generate more efficient machine code by knowing the type of the variable at this point at compile time (I'd love to get feedback on this point from Dmitry). > Personally, I prefer hand-written factories that have an explicit > createEmailService() method with a :EmailService return type declaration, > for example, over the implicitness of a dependency injection container as > the latter disguises and obscures dependencies. We're entering the realm of patterns here; I'm a big fan of IoC myself and even though I use it a lot in my apps, I still find myself calling `$diContainer->get()` more often than not, for example in quick prototypes or CLI scripts. Same thing for ORMs: you may have a full-blown repository for each entity with a strongly typed `find() : ClassName` method, but you may also need to call `$entityManager->find()` directly from time to time. There are also plenty of other use cases in PHP, where you get a variable from a losely typed source (array or whatever), but somehow know that it should be of a given type. - Ben On Tue, 23 Apr 2019 at 07:58, M. W. Moe <mo.mu....@gmail.com> wrote: > Hello, > > Sebastian yes; interface or abstract have been somehow created for that > purpose; even if I find people abusing of those constructs; now if your > container is generalized and represents dynamic data; for instance like a > Message class > it could hold dynamic data types; > > let say: > // abstract public offsetGet > <https://www.php.net/manual/en/arrayaccess.offsetget.php> ( mixed > < > https://www.php.net/manual/en/language.pseudo-types.php#language.types.mixed > > > $offset ) : mixed > < > https://www.php.net/manual/en/language.pseudo-types.php#language.types.mixed > > > $service = $diContainer['email.service'] of ?EmailService; // else throw > TypeError(this type instead of null or EmailService) > > > On Mon, Apr 22, 2019 at 10:07 PM Sebastian Bergmann <sebast...@php.net> > wrote: > > > Am 22.04.2019 um 23:47 schrieb Benjamin Morel: > > > These combine into a third advantage: readability. Today's equivalent > of > > > the above one-liner could be: > > > > > > /** @var EmailService $service */ > > > $service = $diContainer->get('email.service'); > > > if (! $service instanceof EmailService) { > > > throw new TypeError('Expected instance of EmailService, ...'); > > > } > > > > Today's equivalent is, at least for me, is this one-liner: > > > > assert($service instanceof EmailService); > > > > This way the IDE knows what type $service is supposed to be and there > will > > be an exception at runtime (given the appropriate configuration) when > this > > is not the case. > > > > Personally, I prefer hand-written factories that have an explicit > > createEmailService() method with a :EmailService return type declaration, > > for example, over the implicitness of a dependency injection container as > > the latter disguises and obscures dependencies. > > > > -- > > PHP Internals - PHP Runtime Development Mailing List > > To unsubscribe, visit: http://www.php.net/unsub.php > > > > >