Search code examples
javascriptinfinite-loopp5.js

Why am I getting an infinite loop error inp5.js?


With a simple for loop I can trigger a potential infinite loop exception in the p5.js web editor

function setup() {
  var cnt = 0;
  var startTime = new Date().getTime();
  for (i = 0; i < 80000; i++) {
    console.log(cnt++);
  }
  var endTime = new Date().getTime();
  console.log("done in " + (endTime - startTime) + " milliseconds");
}

Gives me output:

Exiting potential infinite loop at line 5. To disable loop protection: add "// noprotect" to your code done in 501 milliseconds

Which is not surprising as I see that the threshold has been increased to 500ms in p5.js-web-editor issues 174

What is surprising, at least to me, is that if I remove any of the semicolons the potential infinite loop is not detected after 500ms and my loop completes.

For example:

function setup() {
  var cnt = 0 // no semicolon here..
  var startTime = new Date().getTime();
  for (i = 0; i < 80000; i++) {
    console.log(cnt++);
  }
  var endTime = new Date().getTime();
  console.log("done in " + (endTime - startTime) + " milliseconds");
}

Gives me output:

79999

done in 1737 milliseconds

My question is, why does removing a semicolon break the p5.js web editor's infinite loop detection?


Solution

  • The p5.js web editor can throw an exception when it detects what might be an infinite loop in a running sketch.

    The logic the web editor uses to detect infinite loops is quite simple, if a loop executes for more than 500ms the exception is thrown. This exception may be confusing as the loop may have been almost ready to complete at the moment the exception was thrown with this message:

    Exiting potential infinite loop

    The word potential is important for understanding the message. This line of code will trigger the exception:

    while(true);
    

    but any finite loop that executes for more than 500ms will also trigger the message.

    In cases where we know a loop is not infinite and we also know that it may take longer than 500ms to complete we can add a noprotect comment to disable infinite loop protection:

    var cnt = 0;
    // noprotect
    while(cnt < 80000)console.log(cnt++);
    

    This code will log the numbers 0 to 79999. Before adding the noprotect comment be sure and review the code carefully. A small mistake can turn a finite loop into an infinite loop:

    var cnt = 0;
    // noprotect
    while(cnt < 80000)console.log(cnt);
    

    By forgetting to increment cnt we have created an infinite loop that will not be detected by the p5.js web editor. This loop will run until the browser detects it and prompts the user to stop it or wait.

    The last part of the question asks why removing a semicolon at the end of a line changes the loop protect behavior. The simple answer is the editor must add instrumentation in order to provide the detection. Missing semicolons cause the editor to not correctly instrument the code. It is a good practice to end javascript statements with a semicolon. See answers to Do you recommend using semicolons after every statement in javascript

    Summary

    • The p5.js web editor can help you avoid long running loops
    • Use a noprotect comment for intentional long running loops
    • use semicolons to end javascript statements