Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:57171 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 84046 invoked from network); 3 Jan 2012 17:04:00 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 3 Jan 2012 17:04:00 -0000 X-Host-Fingerprint: 208.107.21.52 host-52-21-107-208.midco.net Date: Tue, 03 Jan 2012 12:03:59 -0500 Received: from [208.107.21.52] ([208.107.21.52:13999] helo=localhost.localdomain) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 95/86-24045-EF4330F4 for ; Tue, 03 Jan 2012 12:03:59 -0500 Message-ID: <95.86.24045.EF4330F4@pb1.pair.com> To: internals@lists.php.net References: <2095305E-D4E3-4D7E-8218-32EE99688E0C@GMAIL.COM> <2C90FB94-38C4-4270-8C6A-B89304BA8ED8@gmail.com> <159A7CA2-8561-40DA-9434-CAAE12304DDB@gmail.com> <005701ccc0b3$58c8dee0$0a5a9ca0$@alliantinternet.com> <20111222145159.GY25857@alliantinternet.com> <006101ccc0ba$46b81160$d4283420$@alliantinternet.com> <4EF379D8.9000206@lerdorf.com> <4EF37C29.1010206@php.net> <4EF3811A.7080100@lerdorf.com> User-Agent: slrn/pre1.0.0-18 (Linux) X-Posted-By: 208.107.21.52 Subject: Re: [PHP-DEV] Return Type Hinting for Methods RFC From: weierophinney@php.net (Matthew Weier O'Phinney) On 2011-12-22, Rasmus Lerdorf wrote: > On 12/22/2011 10:51 AM, Sebastian Bergmann wrote: > > Am 22.12.2011 19:41, schrieb Rasmus Lerdorf: > > > This is not a step forward. If the author of age_check() really > > > doesn't want to accept type-juggled arguments, then it is easy > > > enough to do a strict type check in the function itself. This puts > > > the effort in the correct place and doesn't encourage this type of > > > coding. > > > > Putting such code into the "correct" place does not change the > > problem that you and Stas describe > > > > function age_check($age) > > { > > if (!is_int($age)) { > > throw new InvalidArgumentException; > > } > > } > > > > With the above code, the caller needs to cast and the writer of the > > age_check() function has to copy/paste/adapt these checks to all > > the correct places ... > > > > I am not advocating type hints for scalars, I am just saying that > > this argument is not really a good one against it. > > But people don't really write code like this in PHP. Um, I do. Often. The first half of the security mantra is "filter input." This also applies to APIs -- you need to ensure you have input you can actually work with. While I might not use the is_int() that Sebastian provided above, I might do the following: if (!is_numeric($age)) { throw new InvalidArgumentException('Did not receive number'); } if ((int) $age != $age) { throw new InvalidArgumentException('Did not receive integer'); } $age = (int) $age; Why? Again, because I need to trust I have a value that I can work with. Throwing an exception as soon as I know I can't work with the value is easier to debug than having another function or operation raise an error later -- these are often much harder to debug, as the source of the input may be several steps removed by that point. This is especially important for library and framework authors, as we need to make the code robust for numerous use cases, most of which will be beyond our immediate control. This makes debugging easier for end users, and also makes documentation simpler. > Which is also why it makes very little sense to add strong typing of > scalars. Why would anyone want to add a feature that lets them do > something they would never do? Despite the example I have above which I personally don't want strong scalar type hinting. I _do_ favor the idea of casting hints, though -- simply because they would simplify my work tremendously, while still giving me the benefits I have if I test my input manually. > The above code is much more likely to do an is_numeric() check and/or a > hard typecast to an int. But throwing an exception when it receives "21" > instead of 21 just isn't something people tend to do. I honestly don't think that was the point of Sebastian's example -- the point was that instead of this: function age_check(int $age) { // use the $age value with the knowledge that it's sane } we're forced to instead do manual checks within the function body itself, which is repetitive, introduces new vectors for errors, and potentially degrades performance. Additionally, it introduces a cost in development -- additional tests and code need to be written. > The only way I see something like this ever happening in PHP is if we > came up with an intelligent approach that actually was type *hinting* > and not strong typing. As in: > > function ((int)$age) { > return ($age > 21) ?: false; > } > > that would gracefully handle interchangeable types. But it gets tricky > once we start thinking about non-numeric strings being passed in there. Agreed on all accounts here. However, if it can be done, I think it would be a huge boon to developers. -- Matthew Weier O'Phinney Project Lead | matthew@zend.com Zend Framework | http://framework.zend.com/ PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc