Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:105347 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 19509 invoked from network); 23 Apr 2019 12:03:18 -0000 Received: from unknown (HELO mail-io1-f68.google.com) (209.85.166.68) by pb1.pair.com with SMTP; 23 Apr 2019 12:03:18 -0000 Received: by mail-io1-f68.google.com with SMTP id m188so10812563ioa.9 for ; Tue, 23 Apr 2019 02:03:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=+0wexnmCZcNhM0JKWnkGmdqoASc0+ADpY4J5ZRMBENs=; b=GNCAdfUuWg4UNcLX6HF1v1LjfcEOVeahoVsxFjItcYXNzNO+taJpBtyoNjWcHdXJJm f8l4qhh8qL5EMwJryS1TZLOJTL/e+THVfxaUKyyCRUeNPAhzRbtx/Xk19WO0xwyWHPl8 Kq67cF1O65AjR9+fIMQlaLsimKIRaz1qABJTXmmdZeyERpB9zXgwg7k1YxJn9VyeUzYW xTwQKq4AvJIklCCOc9JrCBAWpBFxwMYjCenp+R18NobRuub8pMEq85utRcdfgSQzWV6p g2aHbaQZD0M6NQ35dattl0Niki5SKVToDYMnPCsxoLqKx+2STwBwdP8zn1HAgdEflbvj DH1Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=+0wexnmCZcNhM0JKWnkGmdqoASc0+ADpY4J5ZRMBENs=; b=Fkve4MYwbG4xSKYheESG3oX1lCRZBCQoSuGWjK25o1O97bbU0cA1F7SfuPajey8Ozo hWszZsKYFKxwLOp1EL6Y8Odkt9iUdV5609ZQVR63R5tfe6KJu27mHTr2yNhcOt/9+4xt hX2ib8dC2ZF3DYskmNMRF08EXoKqLV87pXioRb2fZOzWHBZuhVyw1BBhWNP5LU7GwE8q vGf0+27tVeuszUFNYeKxHF6MpfSIGp36eM1iYKNFckFIq7+OOhG+Yrzv0UpNlZ5YVjto nxtstJRUi/ibr6bvxAhhM2mAku1Bh+3fAYEhl/WtZNRvEHH4z+kaS3Rrkoi0KH0QOYbL LFxg== X-Gm-Message-State: APjAAAWfPAdulDz8sCpqbqwGSidw8W1KwrJ76gTrnOsZEjOiuAgrdJAS 8AzIeRHZW79EOIydRTB8A63M+jNWnw4zcN8w7+I= X-Google-Smtp-Source: APXvYqzuYYXcnWphxqphFyN8dSz45aydgfNYYyquHfbUj5mdOhDNhgPn5W0JtZcpGrULcPHHllpgs8jPQ518LLGl538= X-Received: by 2002:a5e:a60c:: with SMTP id q12mr5206262ioi.174.1556010219338; Tue, 23 Apr 2019 02:03:39 -0700 (PDT) MIME-Version: 1.0 References: <899de214-607e-9ad8-80cb-eeda5adf8ee6@php.net> In-Reply-To: Date: Tue, 23 Apr 2019 11:03:27 +0200 Message-ID: To: "M. W. Moe" , sebastian@php.net, lemon.head.bw@gmail.com, Stephen Reay , Marcos Passos Cc: PHP internals Content-Type: multipart/alternative; boundary="00000000000063ff7d05872edce0" Subject: Re: [PHP-DEV] Object Type Casting Reloaded From: benjamin.morel@gmail.com (Benjamin Morel) --00000000000063ff7d05872edce0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable 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=E2=80=99s already =E2=80=9Censure a type=E2=80=9D s= yntax, 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=E2=80=99t just be placed= before a variable to ensure a type, similar to a function parameter or typed property? > string $foo =3D 'bar'; > ... > I=E2=80=99m 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 =3D new Foo(); $foo =3D 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 =3D> $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 =3D (Foo) $foo; // or $foo =3D $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 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 > ( mixed > < > https://www.php.net/manual/en/language.pseudo-types.php#language.types.mi= xed > > > $offset ) : mixed > < > https://www.php.net/manual/en/language.pseudo-types.php#language.types.mi= xed > > > $service =3D $diContainer['email.service'] of ?EmailService; // else thro= w > TypeError(this type instead of null or EmailService) > > > On Mon, Apr 22, 2019 at 10:07 PM Sebastian Bergmann > 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 =3D $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 declaratio= n, > > 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 > > > > > --00000000000063ff7d05872edce0--