Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:48402 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 91064 invoked from network); 23 May 2010 05:52:18 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 23 May 2010 05:52:18 -0000 Authentication-Results: pb1.pair.com smtp.mail=larry@garfieldtech.com; spf=permerror; sender-id=unknown Authentication-Results: pb1.pair.com header.from=larry@garfieldtech.com; sender-id=unknown Received-SPF: error (pb1.pair.com: domain garfieldtech.com from 76.96.30.24 cause and error) X-PHP-List-Original-Sender: larry@garfieldtech.com X-Host-Fingerprint: 76.96.30.24 qmta02.emeryville.ca.mail.comcast.net Received: from [76.96.30.24] ([76.96.30.24:58055] helo=qmta02.emeryville.ca.mail.comcast.net) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 9C/24-54147-092C8FB4 for ; Sun, 23 May 2010 01:52:17 -0400 Received: from omta10.emeryville.ca.mail.comcast.net ([76.96.30.28]) by qmta02.emeryville.ca.mail.comcast.net with comcast id LtsA1e0020cQ2SLA2tsFJ8; Sun, 23 May 2010 05:52:15 +0000 Received: from earth.ufp ([98.220.236.211]) by omta10.emeryville.ca.mail.comcast.net with comcast id LtsE1e0044aLjBW8WtsENL; Sun, 23 May 2010 05:52:15 +0000 Received: from localhost (localhost [127.0.0.1]) by earth.ufp (Postfix) with ESMTP id 29435D7A63 for ; Sun, 23 May 2010 00:52:13 -0500 (CDT) Received: from earth.ufp ([127.0.0.1]) by localhost (earth.ufp [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 7zLs-QSEfGxF for ; Sun, 23 May 2010 00:52:13 -0500 (CDT) Received: from luna.localnet (unknown [192.168.42.1]) by earth.ufp (Postfix) with ESMTPSA id 0F7B1D7950 for ; Sun, 23 May 2010 00:52:13 -0500 (CDT) To: internals@lists.php.net Date: Sun, 23 May 2010 00:52:05 -0500 User-Agent: KMail/1.12.2 (Linux/2.6.31-21-generic; KDE/4.3.2; x86_64; ; ) References: <7.0.1.0.2.20100522175819.0a601c68@zend.com> <7.0.1.0.2.20100523073125.0a601600@zend.com> In-Reply-To: <7.0.1.0.2.20100523073125.0a601600@zend.com> MIME-Version: 1.0 Content-Type: Text/Plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Message-ID: <201005230052.05661.larry@garfieldtech.com> Subject: Re: [PHP-DEV] Type hinting From: larry@garfieldtech.com (Larry Garfield) On Saturday 22 May 2010 11:43:50 pm Zeev Suraski wrote: > At 01:01 23/05/2010, Hannes Magnusson wrote: > >On Sat, May 22, 2010 at 22:39, Lukas Kahwe Smith wrote: > > > On 22.05.2010, at 18:30, Josh Davis wrote: > > >> As you wrote, you worked on PHP's _type system_ which is dynamic, > > >> really cool, juggles strings with ints and what not. However, the > > >> topic here is the _type hinting system_. As far as I know, there's no > > >> "weak" type hinting; if a method signature hints for an array and is > > >> given an integer, it throws a catchable fatal error. Therefore, as a > > >> user, what I am familiar to is a strict _type hinting system_. > > >> Anything else would feel inconsistent to me. > > > >I agree. function foo(array $x) {} foo(123); doesn't cast int(123) to > >array(123) so introducing different meaning for scalar types feels > >very very wrong. > > You're ignoring one simple fact - in PHP, scalar types are > interchangeable. Unlike array->scalar which has always been a corner > case and a sketchy one (and I said numerous times that had I rewrote > the language now, array->scalar conversion would have probably > resulted in an error) - string->number, number->string, > string->boolean conversions are a cornerstone of the language. If > you don't like the fact that PHP's scalar types are interchangeable - > you're in the wrong language! > > In terms of consistency, the difference between array type hinting > and scalar type hinting you allude to is negligible in comparison to > the inconsistency with, well, just about every other part of the > language - operators, control structures and built-in functions > (expecting sqrt("64") to fail, since sqrt() expects a > number? expecting if (7) to fail, since it expects a > boolean?). Auto-converting type hinting extends the same semantics > available to internal functions (through zend_parse_parameters()) to > userland functions. That consistency is by far the most important IMHO. > > Zeev I have to largely agree with Zeev here. I'm not an internals developer but I do write a lot of widely used framework-ish open source PHP. The current OO type specifying system I have always mentally viewed, and most people I know seem to view it, as a check not for "is this an X", but "can I treat this as X without things exploding"? In the context of an object, "exploding" would mean a "method not found" fatal. In the context of an array, it would be the dreaded "parameter 1 to foreach() is not an array". The idea is two fold: One, better documentation (especially for code assistance IDEs), and two, if it's going to explode it should explode in a way that's useful in terms of where it exploded. (Vis, the error message is on a useful line and tells me what the actual problem was.) For scalar types, exploding would mean "loss of precision". There is no loss of precision in converting "5" to int(5), so that doesn't explode, nor should it. There is similarly no loss of precision converting from int(5) to float(5), so that also shouldn't explode. "123abc" does have a loss of precision (data would get lost in the conversion) so that should fail both int and float checks. If anything, I'd be even more forgiving than the table in Zeev and Lukas' RFP. float(12) converting to an int doesn't have any precision loss so I don't think that should fail. The RFP includes a variety of good reasons why a more naive strict check is inconsistent to the point of making it a bug rather than a feature. One in particular I want to call out: Everything that comes back from a database does so as a string. To wit: table users(user_id, name, pass, blah); $user_id = $pdo->query("SELECT user_id FROM users WHERE name='bob' AND pass='foo'")->fetchColumn(); doStuff($user_id); function doStuff(int $user_id) { // Whatever. } The above code will fail with the current implementation, even though we know for a fact that user_id is integer data because that column is an int in the database itself. Requiring an extra blind (int) stuffed in there is pointless, and if anything just trains people to blindly cast data without thinking about what it really is. I can see that introducing more bugs than it avoids. --Larry Garfield