php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #75036 Named Continue/Break
Submitted: 2017-08-04 14:27 UTC Modified: 2017-08-04 22:35 UTC
From: php at haravikk dot me Assigned:
Status: Suspended Package: Scripting Engine problem
PHP Version: Next Major Version OS:
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2017-08-04 14:27 UTC] php at haravikk dot me
Description:
------------
So I have (somehow) managed for years to develop in PHP without ever realising that the continue keyword oddly considers a switch statement to be a looping construct. This is a very strange behaviour, and completely functionally useless, but I fear the ship has long sailed on removing it at this point.

To work with switch statements in loops thus requires a numbered continue/break to ensure it applies to the correct construct, however this is a bit unwieldy and has the potential for errors if the depth of any statement changes, and for the most part it's not a very intuitive way to do it when nested structures are usually fairly simple.

What I'd like to propose is that the continue and break keywords gain the ability to optionally specify a construct name. For example:

<?php
    for ($i = 0; $i < 10; $i += 1) {
        switch ($i) {
            case 5:
                continue for;
            break;
        }
    }
?>

Here, PHP would encounter the presence of the "for" keyword, and use it to search for an enclosing for loop, and automatically set the continue correctly (equivalent to setting "continue 2" manually).

A number can still be specified in this form, but applies only to the type of construct named. For example:

<?php
    for ($i = 0; $i < 10; $i += 1) {
        for ($j = 0; $j < 10; $j += 1) {
            switch ($j) {
                case 5:
                    continue for 2;
                break;
            }
        }
    }
?>

Here the continue now applies to the outer for loop, rather than the inner for loop. If I were to set this to "continue for 3", an error would occur (no more for loops).

This is hopefully a bit easier to use, as it means that PHP does the actual calculation to decide what value is required to continue the correct loop type. This could be even easier if we could also leverage labels, like so:

<?php
    outer: for ($i = 0; $i < 10; $i += 1) {
        inner: for ($j = 0; $j < 10; $j += 1) {
            switch ($j) {
                case 5:
                    continue outer;
                break;
            }
        }
    }
?>

Here both for loops are labelled, inner and outer as appropriate, and we use the label name on the continue in order to reference the correct one.

The main problem is that this is a bit more complex syntactically as the label MUST immediately precede an enclosing loop, or else PHP would not know what to do. However, this is by far the simplest/most flexible option, as it requires no counting at all by the developer, as PHP can identify which loop was meant, and continue/break it correctly.


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2017-08-04 14:43 UTC] danack@php.net
Hi there, also nice when people from /r/lolphp drop by.

> This is a very strange behaviour,

No it's not - it's just different from what you're used to.


> and completely functionally useless,

No it's not. Again, it's just not what you're used to.
 

> What I'd like to propose is that the continue and break
> keywords gain the ability to optionally specify a 
> construct name.

This is already possible with goto:


for ($i = 0; $i < 10; $i += 1) {
    for ($j = 0; $j < 10; $j += 1) {
        switch ($j) {
            case 5:
                goto continue_outer;
                break;
        }
    continue_inner:
    }
continue_outer:
}


It's only difference from what you propose is that label goes before the end of the loop but it meets the criteria of "PHP can identify which loop was meant, and continue/break it correctly.".

Oh, it also uses a goto, which some people have a phobia about.
 [2017-08-04 15:01 UTC] php at haravikk dot me
>> This is a very strange behaviour,
> No it's not - it's just different from what you're used to.

Sorry, but in the dozen or so languages I use regularly no other treats switch statements as loops for the purpose of `continue`, so it is absolutely a strange behaviour in that it follows no clear standard, and there is no apparent purpose in it behaving this way.

>> and completely functionally useless,
> No it's not. Again, it's just not what you're used to.

Sorry again, but it really is; it behaves no differently at all to `break`, which makes supporting `continue` within switch statements at best redundant, and certainly misleading and non-standard in addition.

It has nothing to do with my not being used to it; it simply serves no useful purpose and more often creates rather than solves problems, judging by the number of search results from others caught out as I was. But unfortunately changing its behaviour just isn't an option, as deprecating it simply isn't possible to do cleanly.


> This is already possible with goto:
>
> for ($i = 0; $i < 10; $i += 1) {
>     for ($j = 0; $j < 10; $j += 1) {
>         switch ($j) {
>             case 5:
>                 goto continue_outer;
>                 break;
>         }
>     continue_inner:
>     }
> continue_outer:
> }

Thanks for the alternative, but I still feel that this is something that should be possible using the `continue` keyword. I have no particular phobia regarding goto, but I do feel that if it's necessary to workaround a more relevant feature that behaves strangely then it's not a good sign ;)
 [2017-08-04 22:35 UTC] requinix@php.net
-Status: Open +Status: Suspended -Package: PHP Language Specification +Package: Scripting Engine problem
 [2017-08-04 22:35 UTC] requinix@php.net
I don't see a good reason why there should be another way to use continue/break when goto is more than adequate for this.

But anyway, this bug tracker isn't the place to really discuss these things. Head over to the internals mailing list. Also check out the RFC process.
http://php.net/mailing-lists.php
https://wiki.php.net/rfc/howto
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Mar 28 11:01:27 2024 UTC