Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:81142 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 20835 invoked from network); 25 Jan 2015 18:59:37 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 25 Jan 2015 18:59:37 -0000 Authentication-Results: pb1.pair.com smtp.mail=pajousek@gmail.com; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=pajousek@gmail.com; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.192.50 as permitted sender) X-PHP-List-Original-Sender: pajousek@gmail.com X-Host-Fingerprint: 209.85.192.50 mail-qg0-f50.google.com Received: from [209.85.192.50] ([209.85.192.50:39464] helo=mail-qg0-f50.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id B3/64-31595-91D35C45 for ; Sun, 25 Jan 2015 13:59:37 -0500 Received: by mail-qg0-f50.google.com with SMTP id f51so4309258qge.9 for ; Sun, 25 Jan 2015 10:59: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=UWDOaUQKT/e1rTeKh1p8Fa1hmJQxjDIAPM+QFYwmNhw=; b=d2rn8u3b1rP/nU+qjQP30+o0ujlAWLnrVY6vAeMsbTEGSzhZG4zgruH+F/hFQO+ykc DfjVnUr7wFf+9h+GksZMfry9clxGECAzGyrPhsuY+UaAGG/8HSr3+hu0ZYU7UoLAlgkE mVJgorNnXwWixQ0i7SbZjgW8BSqCeQqD4GZ2HrhHqqpeQB7a+KJrXsykiq6Rojw1WYjd yvtiE1hSQ67lBob8iPyPMjuWhYHWemFM3xBQBrLr9Z0JmkKnSlYJ9r6RCALpFDIcDAMe 8oQQfQanqwGVC2sRsijvWkuvItAnDjfuyIdsYUwjnOCoE9Ge6o1UVUX9Tbd8JWekzSEB 0Mfg== MIME-Version: 1.0 X-Received: by 10.224.99.3 with SMTP id s3mr69027qan.79.1422212375225; Sun, 25 Jan 2015 10:59:35 -0800 (PST) Received: by 10.96.209.97 with HTTP; Sun, 25 Jan 2015 10:59:34 -0800 (PST) In-Reply-To: <5893FBAE-EA06-4E06-9E6C-02D4C08C0BCB@ajf.me> References: <41D5BB0B-73AF-488E-968D-90B2878E3178@ajf.me> <90B1885A-E767-484E-8F38-A791E8A3FE9B@ajf.me> <5893FBAE-EA06-4E06-9E6C-02D4C08C0BCB@ajf.me> Date: Sun, 25 Jan 2015 19:59:34 +0100 Message-ID: To: Andrea Faulds Cc: PHP Internals Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Subject: Re: [PHP-DEV] [RFC] Scalar Type Hints From: pajousek@gmail.com (=?UTF-8?Q?Pavel_Kou=C5=99il?=) On Sun, Jan 25, 2015 at 5:05 PM, Andrea Faulds wrote: > Hi Pavel, > Hi, thanks for explaining some things. > > It can *sometimes* be a lossless conversion. Only sometimes. > > For float to int conversion: > > * Floats have the special values INF, NAN and -NAN, which cannot be prese= rved > * Floats have negative zero, which also cannot be preserved > * Fractional components cannot be preserved > * Floats sacrifice precision to allow a wider range of values. They work = with significant figures (scientific notation), unlike integers which alway= s offer full precision. So a particular float value isn=E2=80=99t necessari= ly equivalent to a particular integer value, you have to invent precision t= o do the conversion. 2e10 is dealt with as if it=E2=80=99s 2 with 10 zeroes= after it, but it=E2=80=99s just a number beginning with 2 that has a magni= tude of roughly 10^10. If you convert it to the integer value 20 000 000 00= 0, you=E2=80=99ve just invented values for those trailing digits - those di= gits weren=E2=80=99t necessarily zero, we just don=E2=80=99t know what thos= e digits are. Someone who=E2=80=99s an expert on floating-point might need = to correct me here, but I think this is correct to some extent. What I=E2= =80=99m saying is that float->integer conversion is inherently imprecise. > > For int to float conversion: > > * Values beyond 2^53 or below -2^53 cannot be represented as floats witho= ut a loss of precision > > Some strongly-typed languages allow these conversions implicitly, but I= =E2=80=99m not sure that=E2=80=99s a good thing or something we should want= to copy. Loss of precision isn=E2=80=99t good. If you ask for strict typin= g, you probably want to avoid it, and should get strict typing. > >> And being able to pass a float(1.5) to int and lose the 0.5 value >> doesn't make sense as well, because data will get lost. Neither of >> those feels somehow "predictable" and "natural=E2=80=9D. > > Sure, but it is our existing behaviour. > Yeah, as I said, implicit float to int is IMHO bad and I personally don't like it much, because data loss sucks. But being consistent with existing behavior is probably the right way to do stuff. About the problem with int to float and loss of precision beyond 2^53: I didn't realize that, was thinking just about 32bit integers when I wrote that. But now I wonder how other languages do it, when they are implicitly converting 64bit integers to double precision floating point numbers. > > Unfortunately we don=E2=80=99t have safe casting functions because they w= ere rejected. Alas. > >> So, I think it would be best to choose just one of these two >> approaches and either loosen it a little or make it more strict (so >> data loss doesn't happen). But I guess this approach would be >> inconsistent with how the built-in PHP functions work? > > While it never went to a vote, the Scalar Type Hinting with Casts RFC, wh= ich proposed stricter weak casts, was not well-received. The Safe Casting F= unctions RFC was rejected when it went to a vote. > Oh, I didn't know that stricter weak casts were not well-recieved, because I didn't read internals mailing list back then. But if that's the case, I would gladly see the weak variant of this RFC accepted. Have you thought about splitting this RFC into two? One for adding the weak version and another one for adding the declare strict statement? > > The Scalar Type Hinting with Casts RFC didn=E2=80=99t do that, it was als= o based on values. > > In a dynamically-typed language like PHP, I don=E2=80=99t see why it need= s to be type-based rather than value-based. > Maybe I wrote it wrong; I knew the old RFC had conversions based on values. I just thought the rules based on types (you definitely know what you need to convert and what not before calling a function) would make much more sense, but the problem with 2^53 means that the typed-based conversions are not a great solution either. Pavel Kouril