Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:58760 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 69287 invoked from network); 8 Mar 2012 00:54:38 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 8 Mar 2012 00:54:38 -0000 Authentication-Results: pb1.pair.com header.from=ircmaxell@gmail.com; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=ircmaxell@gmail.com; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 74.125.82.170 as permitted sender) X-PHP-List-Original-Sender: ircmaxell@gmail.com X-Host-Fingerprint: 74.125.82.170 mail-we0-f170.google.com Received: from [74.125.82.170] ([74.125.82.170:53696] helo=mail-we0-f170.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 34/8E-15180-D43085F4 for ; Wed, 07 Mar 2012 19:54:38 -0500 Received: by werh12 with SMTP id h12so4987206wer.29 for ; Wed, 07 Mar 2012 16:54:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type:content-transfer-encoding; bh=mvcHImnrCIVuiljAcdH1TdpJJL5IGH25BPfUFckd68k=; b=Rn4ZMC5yJvet1PgoNHTh2aMmpc1bGlnIob/BM8zUupKhUZM6Iimw7uZQACvpyjjtQ1 yEZu7TWKx4q52D4fFjVJZxzZc0NlhnHVw9aVwi7npnevJ/8T45pkdzhWjF/1njOkxo4Z DpggD782N4L3HSqGpX3hhZedjUFLoadv2MxDdEZcc8fvMwJTTLkSMTF/BPge2Y6gkGXb JdhbFSoGdie6MqpvKaUz1eUwbmatTIg7vPNDrZ1AvOqlswyAQNXfx6FWD4dnFzd06KUm nB+L6XSOeXTD8t5PzFbvfsQr4f/wyaGAfWkeQNuzi/9LPKyiaQu5T7ZAcZbYSRIS46K/ dLnw== MIME-Version: 1.0 Received: by 10.180.95.197 with SMTP id dm5mr19467355wib.20.1331168074988; Wed, 07 Mar 2012 16:54:34 -0800 (PST) Received: by 10.216.137.20 with HTTP; Wed, 7 Mar 2012 16:54:34 -0800 (PST) In-Reply-To: References: Date: Wed, 7 Mar 2012 19:54:34 -0500 Message-ID: To: John Crenshaw Cc: Simon Schick , Kris Craig , Raymond Irving , "internals@lists.php.net" Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Subject: Re: [PHP-DEV] Scalar Type Hinting From: ircmaxell@gmail.com (Anthony Ferrara) John, Thanks a lot for the reply. Comments inline: > You've been spending a lot of time defending these proposals and trying t= o prove wrong feedback that raises concerns. This is preventing you from ac= tually using the feedback to improve the proposals. You are losing out on p= erhaps the biggest advantage of the RFC process, which is that multiple min= ds can work together to hammer out an idea and make it really shine. I only defended what I thought were misconceptions or miss-information about them. After all, the quickest way to a failure is assumption (granted, this is ironic given the rest of this reply)... > You can mince words, but that doesn't change the problem. It is utterly i= nconsistent with the expectations in creates. You'll argue that it creates = an expectation of a type cast, but you'd be wrong =A0in far too many cases.= The syntax is similar enough to the syntax for parameter types in other la= nguages that developers will think of it as basically the same thing. The s= yntax differs however from existing parameter type syntax. That was intentional. That was the point I was trying to make... But let's keep going. > The behavioral difference is also a problem, being too different from par= ameter typing to be useful (it doesn't actually vet the parameter), and yet= close enough to validate the confusion (behaves too similarly to an implic= it conversion). In the end you have a bizarre syntax that looks like one th= ing but is conceptually another, but with a subtle behavioral difference th= at is invisible except when it fails to fail. Again, up to this point, this fits in with what was intended... > I know about the behavioral difference. I'm not talking about a technical= conflict, I'm talking about a conflict in the mind of the developer. Given= function(array $a, (array) $b){} the difference between $a and $b is a ver= y advanced distinction and will be completely lost by the average developer= . I actually think that it's not that advanced of a distinction, but agree to disagree there. > The confusion is made worse by the fact that function(array $a) works, bu= t function(int $a) doesn't, but function((int) $a) does. I know why, but th= e average developer just learning PHP for the first time won't get it at al= l. I won't argue that, but I would make the assertion that there are far more dangerous things that PHP does that the average developer just learning PHP won't get. But again, let's go on... > Sometimes I think you miss the point on purpose. > > In the docs substr is defined as: > string substr ( string $string , int $start [, int $length ] ) > > If I wanted to write the same thing in my own code I would have to write: > function my_substr ( (string) $string , (int) $start , (int) $length ) > > One syntax for the docs, a different one in my code. Now, finally we get to a solid point. I didn't make the connection to the parameter hinting in the docs that you meant. You said "syntax in the docs", and I was thinking about the casting syntax, which is why I asserted that both the syntax and the behavior are inline with the docs. We were both right, just talking about very different things. Now, with that said, I completely see your point. > Well, if you argue that this proposal is actually a typecasting enhanceme= nt and not a parameter type enhancement, then yes, you'd be right. That's n= ot how this is presented though, that's not where it is presented (Scalar T= ype Hinting discussion), that's not when it was presented, and that's not h= ow it is getting perceived or measured. Well, I think that's part of the problem here. People (including both you and me) have so much vested in this discussion, that they are reading things into the proposal that aren't there (both in a good way, and a bad way). > As far as expanding type casting in this way, it doesn't make sense. Ther= e is no precedent, it looks and will get treated like parameter hinting (wh= ich you are saying it isn't), there is no additional functional value, and = very little value of any sort beyond casts (just a tiny documentation boost= and a savings in the number of characters in the few cases where a dumb ty= pe cast is good enough.) Well, I think there's a bit more to be gained on both the static analysis front and the IDE integration front. Additionally, defensive coding now only needs to worry about 1 type, and it puts the onus to ensure proper results on the caller (which is where I would argue it belongs)... > Again, yes, I know that the RFC takes a position on this. My point is not= that the RFC doesn't take a position, my point was that the position taken= "ignores the need that would have caused this sort of code in the first pl= ace." It took a position, because there seemed to be a fair bit of concensus on the list (in current and past dicussions) that this sort of thing should explicitly disallow references. I haven't seen much to the opposite until: > Reference parameters are basically return values. Just because a paramete= r will return a value doesn't mean that the type no longer matters. In fact= , it means that the calling function should EXPECT the type to change, and = EXPECT the value to be modified. One example that occurs to me off hand is = preg_match, where the 3rd parameter is documented as an array reference. Yo= u can actually pass anything, but it's going to be an array when the functi= on returns. That's completely fair. But I'd argue that it's also never going to be consistent, since the cast only relies on the passing of the variable, not the return: function foo ((int) &$foo) { $foo =3D array(); } $a =3D 1; foo($a); How the heck did $a become an array, when it was passed as an int? > You can't raise errors like this on lossy casts. Giving a warning if an i= mplicit conversion loses data (123 + '456xyz', or substr('foo', 'bar')) mak= es sense, but if I explicitly write (int)'456xyz' or (int)23.7, I must not = get a warning about data loss (otherwise it would be difficult/impossible t= o force a deliberately lossy conversion without warnings). Since we can't r= aise warnings on casts, you really won't be able to do it with casted param= eters either (unless you're willing to accept a consistency break). These w= ill be stuck in silence forever. Absolutely we can. The key is not raising errors on all casts, but distinguishing between explicit and implicit casts. Explicit casts always succeed (not sure if that's a good thing IMHO), and implicit casts error. I would consider passing a variable to a hinted parameter would count as an implicit cast, since it's happening **after** the call begins, which means it would issue an error... > Well, if that is the case, you did not succeed. The FC break you original= ly worked to avoid is something that can never happen anyway, and this does= not avoid the most critical FC break. Well, then what's the point? > First, "strict" types (in the sense of not allowing an integer to be pass= ed to a string parameter) are never going to happen in PHP. Even C++ looks = for an implicit conversion and uses that if available. PHP has well defined= implicit conversions between scalars, and there is absolutely no chance th= at PHP is ever going to implement any form of typing that is more strict th= an typing in C++. A strict set of scalar types hint that don't juggle anyth= ing is just not in the cards. To be clear, PHP does not have a well defined implicit conversion between scalars. It has at least 3 of them (actually more, but I'm not going to count). Doing $a + 1 causes one set of conversions. Doing substr($a, 0) does another. Doing echo $a does another (yes, zend_parse_parameters and make_printable_zval have different (albiet slightly) logic). > Second, (bear with me) the form of typing that people seem to have settle= d on before this RFC was introduced is "the same typing as the core, but at= the language level." To use a prior example, the core has: > string substr ( string $string , int $start ){...} > > and the following behavior: > substr('foo', 'bar'); // E_WARNING > substr(123, '1'); // '23' > > I should be able to write an equivalent: > > function my_substr ( string $string , int $start ){..} > > and I should get matching behavior: > my_substr('foo', 'bar'); // E_WARNING > my_substr(123, '1'); // '23' > > Now here's the point, if somehow this proposal were accepted and incorpor= ated into the language it would make it nearly impossible to later achieve = the above. Having both would be confusing, because the behavioral differenc= e is extremely narrow. Your syntax at that point really just silences lossy= implicit conversions and would actually be more similar to what one might = expect from: > function my_substr ( @string $string, @int $start ){..} Fair enough... >> Sure. =A0But I'd argue that anything except foo(int $foo) would have lea= d to FAR more confusion. >> > > I don't think any other syntax is even an option. This syntax is used by = existing type hints in PHP, and in the PHP documentation, and in basically = all generated library documentation, and used for parameter types in every = syntactically similar language. Now we understand each other fully... > And reusing that syntax leads this straight into the dead end indicated p= reviously when talking about the FC objective. Point taken. I've withdrawn the parameter hinting RFC. I truely thank you for helping me understand your concerns. I only wish they could have been shared more clearly at the POC phase so we could have avoided this altogether... Thanks, Anthony