Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:106250 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 99195 invoked from network); 23 Jul 2019 13:46:08 -0000 Received: from unknown (HELO mail-lf1-f54.google.com) (209.85.167.54) by pb1.pair.com with SMTP; 23 Jul 2019 13:46:08 -0000 Received: by mail-lf1-f54.google.com with SMTP id r15so12050815lfm.11 for ; Tue, 23 Jul 2019 04:09:16 -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 :cc; bh=krVpRSXL19aEPRBWPoAIYq3NOOqPuq3YeuvHhqhguH4=; b=uW3sTGqulPxUmT63513wjzIaSK2GywwCbiFI2ETfqo+2MHZbvR8D4oge57Pi9RAk+3 UIURpPd+XPF08nafXqlcLoldaG6tDCmaLKS7lB+q2WKPrruPRw1hsMp7eOXYLZUkthsl Mn2eXi9uT/WT/LwHIGGP5lXC3pbiFdgPjrgEjkMz55+sM/yS+AWNmBUnemorl8hXWq3k Q8PSxsSuWyzvqKY26ZcbXlFpOXjkg5t2tJXPy3HXjwbTCjTnJeId3NjYNVmTjVWqb2xI cJDbmCppUp/aUEKj4jm6xRat1cnc4amy9L00PTpx9QgUZpUgMQXHWMQ4BddyCtBaEKKH gurw== 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:cc; bh=krVpRSXL19aEPRBWPoAIYq3NOOqPuq3YeuvHhqhguH4=; b=EQ7llQKPzQqNzdii3dFJ/ZUT61Qqhff6kZDOIKQh1nLHIcLe4jCXNBuBrmm2k7VZcr SizenZu4yeKW91iG221Wii8WD9h34qEqVArA8SYTqRymGlNMmd3fdlgY+d3DLxNI6s39 uTtKreR4dmCG/f8kp2Hqb7jCFl9rHQEj05WiGIr+xMH9ugzBQQj3q1przwDb87s5gTih ugJIjaiQEnu/IhdjYO+0T3MedCMUmym+ANGSCSdXOgs4vrrbxNKVmnn/vtRgcNLzDIdM O5o2Xz9mYMNtByWyriErcplF9+k+3wtupzoOTCtnQtGb+uLIqbpzc8Snt5JoRIhWvdXe VsHA== X-Gm-Message-State: APjAAAUVWICxoE+Vu1hCuiTEWsyqBsnPFOOfEA7y2Tm/GBK7wtqefcnb qxvK0DkhJa+3Gfp+AJq8ygvJ9MZMRtp8My1m6n4= X-Google-Smtp-Source: APXvYqws90SPWYQSFM0jiN2mHnKX5/6KmcZU7GGZ9s+j3Ryj8Ut69xUJhSIfQgbsKODk4WDuxDY18JGzYjpY7dD2Cyc= X-Received: by 2002:ac2:5dfb:: with SMTP id z27mr34882299lfq.128.1563880155732; Tue, 23 Jul 2019 04:09:15 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: Date: Tue, 23 Jul 2019 13:08:59 +0200 Message-ID: To: Arnold Daniels Cc: PHP Internals Content-Type: multipart/alternative; boundary="000000000000275ea2058e57394b" Subject: Re: [PHP-DEV] [RFC] Strict operators directive From: nikita.ppv@gmail.com (Nikita Popov) --000000000000275ea2058e57394b Content-Type: text/plain; charset="UTF-8" On Wed, Jul 10, 2019 at 11:38 PM Arnold Daniels < arnold.adaniels.nl@gmail.com> wrote: > Hi Nikita, > > Thanks for your feedback. > > I'll fix the textual errors you mentioned. > > * "To compare two numeric strings as numbers, they need to be cast to > > floats." This may loose precision for integers. It is better to cast to > > numbers (int or float) using, with the canonical way being +$x. But I > guess > > that won't work under strict_operators. Maybe we should have a (number) > > cast (it already exists internally...) > > > > Good point. While in most cases you know if you're working with floats or > integers, adding a way to cast to either an int or float would be nice. > Maybe preferably through a function like `numberval($x)` or simply > `number($x), so the `(type)` syntax is reserved for actual types. That > would be an RFC on its own though. > > > > * This has already been mentioned by others: Having $str1 < $str2 perform > > a strcmp() style comparison under strict_operators is surprising. I think > > that overall the use of lexicographical string comparisons is quite rare > > and should be performed using an explicit strcmp() call. More likely than > > not, writing $str1 < $str2 is a bug and should generate a TypeError. Of > > course, equality comparisons like $str1 == $str2 should still work, > similar > > to the distinction you make for arrays. > > > > Ok, fair. I'll change it so <,<=,>,>=,<=> comparison on a string throws a > TypeError, similar to arrays, resources, and objects. > > > > * If I understand correctly, under this RFC "foo" == 0 will throw a > > TypeError, but ["foo"] == [0] will return false. Generally the behavior > of > > the recursive comparison here is that it's the same as strict == but all > > errors become not-equal instead. Correct? I'm not sure how I feel about > > this, as it seems to introduce one more set of semantics next to the weak > > ==, strict == and === semantics there already are. > > > > The syntax would be `$a == $b` (or `$a == [0]`), where $a and $b are a > string/int in one case and both an array in the other case. In the second > case, we can't throw a TypeError as both operands are of the same type. > You can, if you treat == comparisons recursively, which is how I personally would expect them to work. There shouldn't be a difference in behavior between $a == $b and [$a] == [$b] -- either both should throw TypeError if $a and $b have different types, or neither should. > * I also find it somewhat odd that you can't write something like "$obj != > > null" anymore, only "$obj !== null". > > > > To check against null, it's better to use !==. For objects (and resources) > using `!= null` is ok, but for other types, it's currently not. For > example; `[] == null` gives true. > > > > * I think the "solution" to the last three points is a) only support > > numbers in relational operators (<,<=,>,>=,<=>) and throw TypeErrors > > otherwise (maybe modulo provisions for object overloading) and b) allow > > comparing any types in == and !=, without throwing a TypeError. The > > question "Are 42 and 'foobar' equal?" has a pretty clear answer: "No they > > aren't", so there is no need to make this a TypeError (while the question > > "Is 42 larger than 'foobar'?" has no good answer.) I believe doing > > something like this would roughly match how Python 3 works. (Edit: I see > > now that this is mentioned in the FAQ, but I think it would be good to > > reconsider this. It would solve most of my problems with this proposal.) > > > > Besides the argument in the FAQ, having the == and != return do a type > check, means there are a lot more cases where the behavior changes rather > than that a TypeError is thrown. Currently `"foobar" == 0` returns true, > but this would make it return false. So would `1 == true`, `"0" == 0` and > `"0" == false`. To reduce the cases where the behavior changes to a > minimum, it's better to throw TypeErrors for == and !=. > Yes, I can certainly see how that would be an issue. I think both variants have pretty major issues and there may not be a good solution here. In that case I we might want to consider banning == and != entirely under strict_operators mode and force the use of === and !== which will have the usual well-defined semantics. I think that would cause the least overall confusion and wouldn't even be a particularly large loss in terms of functionality. I think the only really useful behavior of == (that is not available with ===) under this proposal was the non-identity object comparison. Nikita > * String increment seems like a pretty niche use case, and I believe that > > many people find the overflow behavior quite surprising. I think it may > be > > better to forbid string increment under strict_operators. > > > > Ok > > > > * A similar argument can be made for the use of &, | and ^ on strings. > > While I have some personal fondness for these, in practical terms these > are > > rarely used and may be indicative of a bug. I think both for string > > increment and string and/or/xor it may be better to expose these as > > functions so their use is more explicit. > > > > These operators make it very easy to work with binary data as strings in > PHP. In other languages you have to work with byte arrays, which is a major > pain. They're also very intuitive; `"wow" & "xul"` is the same as > `chr(ord('w') & ord('x')) . chr(ord('o') & ord('u')). chr(ord('w') & > ord('l'))`. I think these should stay. > > > > > > Regards, > > Nikita > > > > Arnold > --000000000000275ea2058e57394b--