Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:106077 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 80807 invoked from network); 26 Jun 2019 15:34:46 -0000 Received: from unknown (HELO mail-ot1-f51.google.com) (209.85.210.51) by pb1.pair.com with SMTP; 26 Jun 2019 15:34:46 -0000 Received: by mail-ot1-f51.google.com with SMTP id e8so2353364otl.7 for ; Wed, 26 Jun 2019 05:51:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to; bh=7KKOskN9dUqHRwT7uy7+pE8CKDHETqv+8sFFZJv9xqk=; b=GBnIRvBfm0X/wEQ+ojMMp5K1msSKV2gbXVGRatUSgMdoH6jC/n9CXKjcK08JSAp1+g BY0FABAnTlf6k0vSNEj1TwKFFsIJHtQgqlIi9Ctq2UHSlNlvvjcK9c2jHl+uZjSMEcE+ uhAeK2pHUQ0olFKqabjBzD/blhwUd2u0IxMMOQ01T8ngTnyOEnAujgc8iBhIkD0UpCr7 NPJAztJvbyiSyD63Q+MiPAJhRpBWK27g4nkew4tUwnWO94J0NrSapnnOFSSAzF4eHvur VeLFIPbELBL0469MYxLaIkoWraOxH3T1fRq96hWqrpFdCZmtoHLU3f4ggmxrj03EFe9S 4a9g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to; bh=7KKOskN9dUqHRwT7uy7+pE8CKDHETqv+8sFFZJv9xqk=; b=ZFVqQZZ1iX+Dv1qAI2E2VWSvcKCUpfA5IDHmAz+q5RbqY3/K1mzOQ7FZUpHUDa6F/h TY+kjxBjoMs76NwFf3RzWXaq5bEF3xeso9AnekFVkP3bANIv95zlBRlyJYDPVqbs7TCq Qhh4Gl+uhZ0A7YVL9B46bBnWPc6lf5b/a1fRnfpn6JxV434U4QhTN57JxnCyDEPoYp22 PJLBYHVDtIohT/n8npyF+YUS3PVX9G6zZJhCgYyketMdJbYvLPGXklPurVtpny4OzCA4 RDSaGnJ7iL2aBANkXqlI/De6yOKhddJjj6/0VdtTbZtyM7OSM5OBU47YwW45JLsHkCXT dgHw== X-Gm-Message-State: APjAAAVlTMA8NGlKZsu2lsqdnHCz2r3WYXXIcx3U3r8tVfsB4KxXIh3r r2lFMf/IaIijL55rutUwoESWHKV62GBh4ASUplENGViw+fs= X-Google-Smtp-Source: APXvYqwKOEePx7n0+zV+j/iP2K88Qmq5dhjGrNciiujA95ZzOA1ZgOR9Z8rVYVXTxEQFArmQJUfyJNuXnetF2yL2GrY= X-Received: by 2002:a9d:3c2:: with SMTP id f60mr3173972otf.187.1561553470373; Wed, 26 Jun 2019 05:51:10 -0700 (PDT) MIME-Version: 1.0 References: <6D1026FF-ECF1-4604-91A8-D290D37CC238@cschneid.com> In-Reply-To: Date: Wed, 26 Jun 2019 14:50:59 +0200 Message-ID: To: PHP Internals Content-Type: multipart/alternative; boundary="000000000000e64854058c397f6e" Subject: Re: [PHP-DEV] [RFC] Strict operators directive From: arnold.adaniels.nl@gmail.com (Arnold Daniels) --000000000000e64854058c397f6e Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Wed, Jun 26, 2019 at 12:39 PM Claude Pache wrote: > > > > Le 26 juin 2019 =C3=A0 11:36, Benjamin Morel = a > =C3=A9crit : > > > >> (...) could be the case depending on a declaration somewhere else in t= he > > source code. > >> That's the confusion Claude and I were talking about: You cannot be su= re > > what a very simple line of code does. > > > > Oh, I see. You mean that only replacing some of the current results wit= h > > TypeErrors would be acceptable; returning a different value would not. > > This makes a lot of sense, but once again prevents the language from > slowly > > moving towards something different (and better), leaving it stuck in it= s > > legacy forever. > > > > I'm starting to believe that a joint effort to fork PHP if the only way > out > > :( > > > > Ben > > > It would be something =E2=80=9Cdifferent=E2=80=9D, but not necessarily = =E2=80=9Cbetter=E2=80=9D. > > Programmers may intentionally rely on the current semantics when comparin= g > numeric strings, e.g. in the following cases: > * values that are grabbed from a database using a driver that returns onl= y > strings (or nulls); > * values that are read from $_POST and that ultimately stems from some > HTML element. > > ------- > > It was certainly a fundamental design error to have both implicit type > conversion and operators that did different things based on the type of > their operands. That leads to the infamous `"1" + 1 =3D=3D 11` problem in > JavaScript, or the the "3" < "24" problem in PHP. That could have been > avoided in two ways: > * either by forbidding implicit conversion; > * or by using different operators for different types (as does Perl). > > Now, returning to the case of the comparison operators like `<` or `=3D= =3D`. > Instead of killing implicit conversion and redefining the meaning of thos= e > operators in cases that are *not* just edge case, it may be preferable to > use the other approach: > > * in some strict mode, reserve `<`, `=3D=3D` etc. for numeric comparison,= and > throw a TypeError one of the operand is not numeric; > > * If we deem it worth, define a new operators for string comparison. > (Although I=E2=80=99m not really sure it is worth: we have `strcmp()` and= `=3D=3D=3D` for > byte-to-byte comparison, and the Collator class for alphabetical sorting > that actually works in languages not restricted to unaccented latin > characters.) > > =E2=80=94Claude > > > Forbidding implicit type conversion completely is taking it to far. Some operators like string concatenation (`.`) can perform conversions just fine= . The issue at hand is limited to operators that are affected by the value (not only the type) of the operands. Specifically: 1. When using numeric strings with relational operators. This includes statements like `"16" =3D=3D "016"`. 2. When comparing two arrays, eg `[null] =3D=3D [0]` and `[0] =3D=3D ["foo"= ]`, or comparing two objects. 3. In a `switch` statement. -- 3. Whether a switch is or isn't affected by `strict_operators` should be determined via a secondary vote. 2. Concerning the `=3D=3D` and `!=3D` with arrays and objects. There is cur= rently a range of differences when compared to the effect of `=3D=3D=3D` and `!=3D= =3D`. To what extent is the typecasting intended? Some cases like `[0] =3D=3D [false= ]` can be common. As such widening primitive conversion from bool to int might be a good idea (in general). Beyond that allowing cases like `[[]] =3D=3D [false]` would undermine the purpose of this RFC as it allows seemingly self-contradicting statements to evaluate to true, like $a =3D=3D $b && $a =3D=3D $c && $b !=3D $c with $a =3D [false]; $b =3D [0]; $c =3D [[]]; 1. The `strict_types` directives already require you to cast raw data from `$_GET`/`$_POST` or a database. In case using the directive would disallow strings, arrays, and objects as operands for relational operators (throwing a `TypeError`), would still require explicit casting. The difference is that when you forget to do that or copy the code from a code base where this isn't required, you'd always get a `TypeError`, rather than it giving a different result. I don't think a `TypeError` should not be thrown based on the value of an operand, only based on the type. Also. implicitly casting strings to numbers, but not casting other types (like arrays), is only making the logic of operators more complex and inconsistent. Disallowing relational operators `=3D=3D`, `!=3D`, `<`, `>`, `<=3D`, `>=3D` and `<=3D>` for string= s altogether, requiring the use of a function is an option. However, IMHO this is killing a fly with a cannon, as the problem is limited to "copy/pasted code for comparing numeric strings from a source file that doesn't use strict_operators to a file does use it". -- So, should a directive, declared at the top of the file, affect how the code in that file is executed? Afaics YES, that's exactly what it's for > The declare construct is used to set execution directives for a block of code. (https://www.php.net/declare) --000000000000e64854058c397f6e--