Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:83586 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 92558 invoked from network); 23 Feb 2015 16:24:53 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 23 Feb 2015 16:24:53 -0000 Authentication-Results: pb1.pair.com header.from=php@tutteli.ch; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=php@tutteli.ch; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain tutteli.ch designates 80.74.154.78 as permitted sender) X-PHP-List-Original-Sender: php@tutteli.ch X-Host-Fingerprint: 80.74.154.78 ns73.kreativmedia.ch Linux 2.6 Received: from [80.74.154.78] ([80.74.154.78:39006] helo=hyperion.kreativmedia.ch) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id B8/26-01128-1545BE45 for ; Mon, 23 Feb 2015 11:24:51 -0500 Received: (qmail 18303 invoked from network); 23 Feb 2015 17:24:45 +0100 Received: from cm135-167.liwest.at (HELO RoLaptop) (81.10.135.167) by ns73.kreativmedia.ch with ESMTPSA (AES256-SHA encrypted, authenticated); 23 Feb 2015 17:24:44 +0100 To: "'Anthony Ferrara'" Cc: "'PHP internals'" References: <2e4694f9805ee81ea0b2c79eab06c2d6@mail.gmail.com> <54EA5EDA.8010605@gmail.com> <54EA6A99.5010609@gmail.com> <54EA7F15.9030606@gmail.com> <54EA891B.6030405@gmail.com> <09b9ee836c04b1750614a91bd39a5bed@mail.gmail.com> <54EA97A2.4010701@gmail.com> <003901d04f42$8ec315d0$ac494170$@tutteli.ch> <005801d04f73$2c59a450$850cecf0$@tutteli.ch> In-Reply-To: Date: Mon, 23 Feb 2015 17:24:44 +0100 Message-ID: <005c01d04f85$3c1a5df0$b44f19d0$@tutteli.ch> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Mailer: Microsoft Outlook 14.0 Thread-Index: AQIDXD7ehmaYKzbAddTs7O1sB4MzmgIw+OLdAe4e2iYCibfnDQEmdWqtAiDZcfAB4cR2SQJXxpD6Ais01rQBOuFyBwIXH55kAgBLRkUB7WPLqgLlji1tAopE+uibsBEUcA== Content-Language: de-ch Subject: AW: [PHP-DEV] JIT (was RE: [PHP-DEV] Coercive Scalar Type Hints RFC) From: php@tutteli.ch ("Robert Stoll") Hey Anthony, > -----Urspr=C3=BCngliche Nachricht----- > Von: Anthony Ferrara [mailto:ircmaxell@gmail.com] > Gesendet: Montag, 23. Februar 2015 15:28 > An: Robert Stoll > Cc: PHP internals > Betreff: Re: [PHP-DEV] JIT (was RE: [PHP-DEV] Coercive Scalar Type = Hints RFC) >=20 > Robert, >=20 > > [Robert Stoll] > > Sure, "a" was just an example to illustrate the problem. I figured = it would not be necessary to say that the value of $b can > be completely unknown by the static analyser -> could come from user = input, from a database, from unserialising code etc. > (but probably that is what you meant with "this isn't the general = case" below). > > > > Assuming statically that $a is int or $b is string is erroneous in = this context. > > > > Another problem to illustrate that a top type or at least some form = of union type is required: > > > > function foo($x, $y, $z){ > > $a =3D 1; > > if($x){ > > $a =3D "1"; > > } > > If($y > 10){ > > $a =3D []; > > } > > If($z->foo() < 100){ > > $a =3D new Exception(); > > } > > echo $a; > > return $a; > > } > > > > How do you want to type $a without using a union type? >=20 > Actually, this case is reasonably easy to handle. There's a = representation called SSA (Static-Single-Assignment) that you > move code to prior to doing type analysis. Basically, at a really high = level, it would rewrite the code to this: >=20 > function foo($x, $y, $z){ > $a =3D 1; > if($x){ > $a1 =3D "1"; > } > $a2 =3D =CE=A6($a, $a1); > If($y > 10){ > $a3 =3D []; > } > $a4 =3D =CE=A6($a2, $a3); > If($z->foo() < 100){ > $a5 =3D new Exception(); > } > $a6 =3D =CE=A6($a4, $a5); > echo $a6; > return $a6; > } >=20 > Where =CE=A6 is a function that chooses the value based on the branch = of the graph that entered it. > There are a few ways to implement it in practice, one would be to = generate a variant.=20 [Robert Stoll] I am aware of SSA but it does not enable you to by-pass union types = (sure in certain cases as below but that is it). Maybe I got one of your email wrong (or did not consider the context = enough) but I got the impression that you think union types would not be = necessary in strict mode. But they are, due to the fact that PHP = supports data polymorphism (even for variables).=20 There are cases where SSA is not applicable at all. Consider the above = code but use $this->a instead of $a. In the end $this->a will have the = type mixed in your static analyser. But I see that you are well aware of it. Recki-CT seems to be a nice = project btw. :) > But another would be to generate > different code paths. Considering that $a5 will be the result if = $z->foo() < 1000 no matter what the prior conditionals are, > you could invert the code to push that check first, making it: >=20 > function foo($x, $y, $z) { > if ($z->foo() < 1000) { > $a =3D new Exception(); > echo $a; > return $a; > } > if ($y > 10) { > echo []; > return []; > } > if ($x) { > echo "1"; > return "1"; > } > echo 1; > return 1; > } >=20 > That transform can be done by the compiler, and hence never need you = to do anything. We still compiled without variants, > and the analysis job wasn't that difficult. >=20 > There will be cases of course where this won't work. And in those = cases we could either not compile, or generate a variant. >=20 > However, I would like to point out something. If you added a return = type, and ran that code in strict mode, it would error. A > static analyzer can pick up that error and tell you about it. [Robert Stoll]=20 How come? You mean because PHP does not offer the possibility of union = types yet or why? Specifying a return type mixed would be perfectly = legal here even in strict mode. >=20 > So really, we're not talking about valid strict code here (tho the = same problem does exist inside strict bodies, and > techniques can be done here the same. [Robert Stoll]=20 I get more and more the impression that you talk about strong typing = here or a language which is statically typed instead of the strict mode = as presented in your v0.5 RFC or the coercive RFC as in this discussion. Or is this discussion about dynamic vs. static and I missed it? >=20 > For more info, check out: > https://github.com/google/recki-ct/blob/master/doc/5_phi_resolving.md >=20 > >> > >> And hence know **at compile time** that's an error. > >> > >> This isn't the general case, but we can error in that case (from a > >> static analysis perspective at least) and say "this code is too = dynamic". In strict mode at least. > > > > [Robert Stoll] > > If you go and implement a more conservative type system than the = actual dynamic type system of PHP well then... you > can do whatever you want of course. > > But if you do not just want to support just a limited set of PHP = then you will need to include dynamic checks in many > places. Or do you think that is not true? >=20 > I think with strict type declarations, the 'limitations' are far less = than you'd think. Yes, there will be cases (like variable > variables, > etc) where valid strict code won't be analyzable. But I haven't seen = var-vars in the wild in a while. So I think my assertion is > fair: the majority of *valid* strict-typed code will be analyzable. = Where the majority of coercive won't be. [Robert Stoll]=20 I agree with your first sentence but only in the case that your "strict = type declarations" include somehow polymorphic declarations as well. = Otherwise I would need to object vehement. Consider the following: $b =3D 1 + 2; $a =3D [1] + [2]; If you would claim that + can only have one strict type (num -> num) for = instance, then no! Strict-typed code in this sense is not able to = analyse most valid strict-typed code. But I guess you used an unfavourable wording and hence I do not go into = more arguments here. As for your second sentence. Analysable are both variants. The coercive = one will just need more effort and computer power - maybe something = which you consider to be not feasible. Fair enough, but the claim is = wrong. It is really not a question about strict-typed or coercive. From a = static analyser point of view it can still predict the types equally = well (as I said with lot more effort) - it only gets more complicated = for the developer of the static analyser since she has to take implicit = conversions into account as well when resolving a function, an overload = respectively, has to propagate the implicit conversions forward etc. It = is more complicated but doable. Of course, the resulting type system is = uglier (and complex) than a type system for a strict-typed version and = way uglier than a strongly and strict typed version (e.g. Haskell's type = system as paragon). I haven't seen variable variables in the wild for a while either. Yet, = variable function calls are quite common and dynamic includes are part = of almost all template system in know. So in the end it really matters what a static analyser wants to achieve = (support all features or only a sub-feature) and if it wants to remain = compatible with PHP without changing behaviour (even if only a subset is = supported) Your comparisons with Recki-CT are only helpful to a certain degree = (they are very helpful, do not get me wrong). Yet, Recki-CT does not = have the same behaviour as PHP. Consider the following: function foo(int $x){} $a =3D 1; if($x){ //$x is always false $a =3D 1 / $y;=20 } echo $a; foo($a); Is translated according to the docs of Recki-CT to the following after = SSA (annotated with types) function foo(int $x){} double $a =3D 1.0 if($x){ // double $a1 =3D 1 / $y; } double $a2 =3D =CE=A6($a1, $a); echo $a2; //will no longer be 1 but 1.0 if the if branch was not taken, = behaviour was changed by the compiler foo($a2); //will result in an error of course Btw. How do you type echo in Recki-CT? I guess you use conversions here = as well ;-) or are object with __toString() not supported any longer? >=20 > Anthony >=20 > -- > PHP Internals - PHP Runtime Development Mailing List To unsubscribe, = visit: http://www.php.net/unsub.php