Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:105333 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 41190 invoked from network); 23 Apr 2019 01:02:55 -0000 Received: from unknown (HELO out3-smtp.messagingengine.com) (66.111.4.27) by pb1.pair.com with SMTP; 23 Apr 2019 01:02:55 -0000 Received: from compute7.internal (compute7.nyi.internal [10.202.2.47]) by mailout.nyi.internal (Postfix) with ESMTP id 8A0FA21B2A for ; Mon, 22 Apr 2019 18:03:09 -0400 (EDT) Received: from imap26 ([10.202.2.76]) by compute7.internal (MEProxy); Mon, 22 Apr 2019 18:03:09 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to:x-me-proxy :x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm2; bh=pdYZ2H qlzBAaebloyLUsrKlFHiQP3WZ/y/QRT3lK/zU=; b=1LBdM9TuEs75kCACRn8QmT 9GdgUYP2jFIlVXMTDgMjmrbr6XGcfFYG/6dwNV+3HxnZP17mOQYrtb/XXWT1AnfF qNcZXJPrOu0fI4okSbrFP8AYBEsxrXJObuKpkBMSygAJC+qyrajPDsDwp+64x84O d1e7tzfDIs6yDj1MW5SpLlBxPEsIHO23fd/qvwZynUlIaYj25vB4i2K/t991i7DP WjotrP4OI+R26wRRrOvjkjYGsNQzNKB7KL+t6cAYMCRr5lnzXn15vpmua5cwIOnq ANXz0LTayJM9mt9X6+bYdKWVuLRkQ5plAgG4GaVc+ItvOCBnOavkMmG9cZgpEY3Q == X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeduuddrgeejucetufdoteggodetrfdotffvucfrrh hofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgenuceurghi lhhouhhtmecufedttdenucenucfjughrpefofgggkfgjfhffhffvufgtsehttdertderre dtnecuhfhrohhmpedfnfgrrhhrhicuifgrrhhfihgvlhgufdcuoehlrghrrhihsehgrghr fhhivghlughtvggthhdrtghomheqnecuffhomhgrihhnpegvgihtvghrnhgrlhhsrdhioh enucfrrghrrghmpehmrghilhhfrhhomheplhgrrhhrhiesghgrrhhfihgvlhguthgvtghh rdgtohhmnecuvehluhhsthgvrhfuihiivgeptd X-ME-Proxy: Received: by mailuser.nyi.internal (Postfix, from userid 501) id 34E48B4505; Mon, 22 Apr 2019 18:03:09 -0400 (EDT) X-Mailer: MessagingEngine.com Webmail Interface User-Agent: Cyrus-JMAP/3.1.6-443-g918f9d3-fmstable-20190416v3 Mime-Version: 1.0 X-Me-Personality: 10727885 Message-ID: In-Reply-To: References: Date: Mon, 22 Apr 2019 18:03:08 -0400 To: internals@lists.php.net Content-Type: text/plain Subject: Re: [PHP-DEV] Object Type Casting Reloaded From: larry@garfieldtech.com ("Larry Garfield") On Mon, Apr 22, 2019, at 4:47 PM, Benjamin Morel wrote: > Hi internals, > > I'd like to revive an old discussion about > object type casting. > > The idea would be to allow (ClassName) casting: > > $service = (EmailService) $diContainer->get('email.service'); > > The above code would throw a TypeError if the value is not an instance of > the given class. I see the following advantages: > > - Type safety: we can be sure that the value is of the correct type or that > we'll get an Error. This syntax allows to fail early if the variable > happens to not be of the expected type, and avoids much more verbose checks; > - Static analysis: IDEs and static code analysis tools can now understand > the type of the variable, without having to resort to `@var` annotations. > > 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, ...'); > } > > Which is a lot of boilerplate code that could be easily avoided by > introducing this new syntax. > > Before moving forward and working on a formal RFC, I'd like to hear your > thoughts: what's your early feeling about this? Did I miss other > discussions around this subject? Are there any technical issues that come > to mind? Could this feature help the upcoming JIT compiler produce more > efficient machine code by knowing the type of the variable at compile time? > etc. > > Note: "casting" might not be the perfect name here as what we're really > doing is a type check, but this reuses the type casting syntax and > resembles Java's object casting. > > Thank you, > Ben Hi Ben. First thought: I'm all for easy ways to be more type-explicit, so yay on the concept. Second thought: That said, how many use cases for that are there other than function boundaries, which we already have covered? I can think of two: foreach() loops and returns where you know the return type with more specificity than the method you're calling. Example: /** @var Foo $foo *// foreach ($arrayOfFoo as $foo) { $foo->bar(); } Example from PSR-14, in which you know the object you're getting back MUST be the same one that's passed in but dispatch() has no return type: /** @var Foo $event **/ $event = $dispatcher->dispatch(new Foo()); The second I can see being easily handled by this syntax. The former, how would that look? Third thought: Casting is the wrong name here, and feels also misleading as a syntax. (float)$anInt means "type coerce this thing into a float", which cannot error. You're suggesting (Foo)$bar to mean "if this isn't already a Foo, throw." That's a very different behavior semantic for the same syntax. Is that a land mine? I would expect (Foo)$bar to mean "recast $bar into an instance of Foo if possible, and error if not". Which... I suppose "is it already" is a subcase of that, but it's still not the behavior I'd expect from that syntax. --Larry Garfield