# bool values and increment operators?

- Thread: https://externals.io/message/104932
- Original archive: https://news-web.php.net/php.internals/104932
- Started by Dan Ackroyd on 2019-03-25T14:43:34+00:00
- Messages: 8
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #104932 — Dan Ackroyd — 2019-03-25T14:43:34+00:00

URL: https://externals.io/message/104932#104932

Hi internals,

So this code:

    <?php

    declare(strict_types=1);

    $i = true;
    $i++;
    var_dump($i);
    $i--;
    var_dump($i);


    $i = false;
    $i++;
    var_dump($i);
    $i--;
    var_dump($i);

outputs:

    bool(true)
    bool(true)
    bool(false)
    bool(false)

which is quite surprising on multiple levels.

Does anyone know if this behaviour is deliberate, or is it just an
oversight that could have an RFC applied to it?

cheers
Dan
Ack

btw I realised that the behaviour is like it is, from someone asking
for help debugging this code:

<?php
$i=0;
$j=2;
$exit = 0;
while(10-$i++||$i=0||--$j){
    echo$i.' - '.$j."\n";
    if($exit++ == 30) `exit()`;
}

---

## #104933 — Christian Schneider — 2019-03-25T15:03:37+00:00

URL: https://externals.io/message/104932#104933

Am 25.03.2019 um 15:43 schrieb Dan Ackroyd <danack@basereality.com>:
> So this code:
> 
>    <?php
> 
>    declare(strict_types=1);
> 
>    $i = true;
>    $i++;
>    var_dump($i);
>    $i--;
>    var_dump($i);
> 
> 
>    $i = false;
>    $i++;
>    var_dump($i);
>    $i--;
>    var_dump($i);
> 
> outputs:
> 
>    bool(true)
>    bool(true)
>    bool(false)
>    bool(false)
> 
> which is quite surprising on multiple levels.

The documentation has a highlighted box stating
"Note: The increment/decrement operators only affect numbers and strings. Arrays, objects and resources are not affected. Decrementing `NULL` values has no effect too, but incrementing them results in 1."

I guess bools should be added to the list of things not affected.

- Chris

---

## #104934 — Chase Peeler — 2019-03-25T15:08:31+00:00

URL: https://externals.io/message/104932#104934

On Mon, Mar 25, 2019 at 11:03 AM Christian Schneider <cschneid@cschneid.com>
wrote:

> Am 25.03.2019 um 15:43 schrieb Dan Ackroyd <danack@basereality.com>:
> > […]
>
> The documentation has a highlighted box stating
> "Note: The increment/decrement operators only affect numbers and strings.
> Arrays, objects and resources are not affected. Decrementing `NULL` values
> has no effect too, but incrementing them results in 1."
>
> I guess bools should be added to the list of things not affected.
>
> $i = false;
$i+=1;
var_dump($i);

that outputs
int(1)

I'd say that
1.) Update the documentation to add booleans to the second list
2.) Update the documentation to remove the second list - anything not in
the first list is not affected.
3.) Update the language so that ++ and -- cast booleans to ints.

I don't think #3 is actually a good solution.


> - Chris
>
>
> --
> 
> 
>
>

-- 
Chase Peeler
chasepeeler@gmail.com

---

## #104937 — Rowan Collins — 2019-03-25T15:25:16+00:00

URL: https://externals.io/message/104932#104937

On Mon, 25 Mar 2019 at 15:03, Christian Schneider <cschneid@cschneid.com>
wrote:

> The documentation has a highlighted box stating
> "Note: The increment/decrement operators only affect numbers and strings.
> Arrays, objects and resources are not affected. Decrementing `NULL` values
> has no effect too, but incrementing them results in 1."
>


The `NULL` part of that has always baffled me. Why should ++ not be
symmetrical with -- here?

In general, documenting what we currently do is great, but is separate from
agreeing that it's what we *should* do.

Regards,
-- 
Rowan Collins
[IMSoP]

---

## #104939 — Andrey Andreev — 2019-03-25T15:43:08+00:00

URL: https://externals.io/message/104932#104939

Hi,


>
> 1.) Update the documentation to add booleans to the second list
> 2.) Update the documentation to remove the second list - anything not in
> the first list is not affected.
> 3.) Update the language so that ++ and -- cast booleans to ints.
>

4.) Emit warnings in those cases?

I don't see a problem with how it currently works, but I do see a
problem with it being silent.

Cheers,
Andrey.

---

## #105133 — me@jhdxr.com — 2019-04-07T16:08:36+00:00

URL: https://externals.io/message/104932#105133

It there anyone working on this? If not, I'd like to prepare a RFC targeting PHP 8 to address this issue.

In addition, I'm thinking whether it's possible and necessary to add a global strict mode (like "use strict" in js) in PHP 8 to deal with this kind of unexpected surprise. I know we have declare(strict_types=1) but it only works for functions and it's limited to call from current file.

-----Original Message-----
From: Andrey Andreev <narf@devilix.net> 
Sent: Monday, March 25, 2019 11:43 PM
To: Chase Peeler <chasepeeler@gmail.com>
Cc: Christian Schneider <cschneid@cschneid.com>; Dan Ackroyd <danack@basereality.com>; PHP internals <internals@lists.php.net>
Subject: Re: [PHP-DEV] bool values and increment operators?

Hi,


>
> 1.) Update the documentation to add booleans to the second list
> 2.) Update the documentation to remove the second list - anything not 
> in the first list is not affected.
> 3.) Update the language so that ++ and -- cast booleans to ints.
>

4.) Emit warnings in those cases?

I don't see a problem with how it currently works, but I do see a problem with it being silent.

Cheers,
Andrey.

---

## #105134 — Rowan Collins — 2019-04-07T17:15:51+00:00

URL: https://externals.io/message/104932#105134

> In addition, I'm thinking whether it's possible and necessary to add a global strict mode (like "use strict" in js) in PHP 8 to deal with this kind of unexpected surprise. I know we have declare(strict_types=1) but it only works for functions and it's limited to call from current file.


I'm not a fan of a generic "strict mode" the way JS has it, because it 
only works once: if you add more behaviours later, the BC break is just 
as bad as if the switch wasn't there. I wonder if in 10 years time, 
someone will propose a "use stricter" mode.

Perl's "pragma" system is more flexible, and notably works at the file 
or block level, like PHP's declare statements. The most common pragmas 
are "strict", "warnings", and "feature", each of which has a set of 
sub-categories which can be individually enabled and disabled. You can 
also opt into all features as of a particular version (and require that 
version), again within a single lexical scope. The downside is that this 
leads to a lot of different combinations, in keeping with the Perl motto 
of There More Than One Way To Do It.

The big downside of all this is that even if the compiler understands 
what all the combinations of flags will do, the human reading the code 
won't necessarily, so having declare(increment_warnings=1) probably 
doesn't add much over just documenting the change somewhere.

Regards,

-- 
Rowan Collins
[IMSoP]

---

## #105135 — Dan Ackroyd — 2019-04-08T02:18:16+00:00

URL: https://externals.io/message/104932#105135

>
> It there anyone working on this?

I'm planning to. I've just been also thinking about arrays and nulls
with pre/post inc/decrement.

I'm guessing code that is 'intentionally' doing:

$foo = false;
$foo++;

and

$foo = [];
$foo++;

are going to be relatively rare, and so would be small BCs.

Whereas code that is doing:

$foo = null;
$foo++;

e.g. through something like:

error_reporting(0);
$bar = [];
$foo = $bar['bad_key'];
$foo++;

Are going to be more common, and so would be a large BC break.

Though seeing as since PHP 7.0 we have the null coalesce operater,
that code can be re-written to have an explicit default, and not emit
an error as:

$bar = [];
$foo = $bar['bad_key'] ?? 0;
$foo ++;

> In addition, I'm thinking whether it's possible and necessary to add a global
> strict mode (like "use strict" in js) in PHP 8 to deal with this kind of unexpected
> surprise. I know we have declare(strict_types=1) but it only works for functions
> and it's limited to call from current file.

A global mode wouldn't be good - it would have the same problem as ini
settings have; libraries that are written needing one mode, can't be
sure they would be used in that mode.

An alternative idea of having settings per namespace has been
mentioned before with the config settings per library managed through
something at the package manager layer, e.g. Composer.

cheers
Dan
Ack
