Achive Higher performent solutions with Greater high level control of break(num/label), continue(-), skip(-), equivalent of low level 'goto' , with block chain of statments

Continue to push the boundaries of performance that javascript solution to problems can deliver in a high-level language, that only be achieved in more tedious assemble, low level c/C++ will get you.

The proposal is to improve the flow control statements in Loops e.g for, while, do, which allows for better-optermized solutions to problems, avoiding some tricks, to do the same, which slight would defeat the purpose, as tricks come with hidden cpu cycle overhears.
I will provide examples of solution that should generate more optimize assembly code and have faster run times for early kick out solution, where there can be less boiler plat to handle early kickout and positive cases.

Propose that with in a since function block scope, to keep it simple at first, later it could possible be expanded to indefinite level, however, that would result in language become too complex.

Proposal 1:
Allow changing of break, continue, skip in sequence, to control multiple loops and not just the most inner loop, from with in the most inner loop.
e.g

for(let i = 0; i < 10; i++) {
for(let j =0;j<10;j++) {
 console.log(i + ":" + j+",");
 if (j ==5) {
  break;
  continue;
 }
}
console.log("Tail assume correct count increments or similar code");
}

output: 1:1,1:2,1:3,1:4,1:5,2:1,2:2,2:3,2:4,2:5,....

Proposal 2:
Block skip operator, which allows for a section of code to totally be skip, such that a solution can have multiple manual typed sections, where not all may apply to the current iteration evaluation, so want them to be skipped. This could be achieved with map of functions to be call based on a condition, but this adds additional complexity and low-level code generation. This is my mind would allow process to better skip instructions and branch predict, than over head of function calling may have, but probably with compiler optermizations results in the same optermization of code block of all if statements for skips instruction being hoisted, and then it running the blocks.

for (let i = 0; i < 10; i++)
{
 {
  skip;
  console.log("First Block,");
 }
 {
  console.log("Second Block,");
 }
}
output: Second Block,Second Block,Second Block,Second Block,Second Block,Second Block,...

Proposal 3:
Allow parametrized version of a break, continue, skip that take either an integer or label to control the exit of multiple neasted loops. The integer version say how many loops to skip, not present current loop, if larger than 0, it will skip, break or continue until that many times until the count has decrease to 0.
e.g number

for (let i = 0; i < 5; i++) {
 for (let j = 0; j < 5; i++) {
   for (let j = 0; j < 5; i++) {
     
      console.log("K");
      break(3);
   }
 }
}

output: K

e.g label

:label-first-loop:
for (let i = 0; i < 5; i++) {
:label-second-loop
 for (let j = 0; j < 5; i++) {
:label-third-loop
   for (let j = 0; j < 5; i++) {
     
      console.log("K");
      break(label-first-loop);

    label-first-block: {...}
    label-second-block: {....}
    label-third-block: {....}
   }
 }
}

output: K

By doing this one can write much better solutions, like the following below:

function johnMary(str) {

  const strJohn = "John"; // may not have null terminating as also check as literal charater.
  const strMary = "Mary";
  const strWasley = "Wasley";

  //str += '\u0000';

  let countJohn = 0;
  let countMary = str.length;
  let countWasley = 0;

  for(let i = 0; i < str.length; i++) {    

    (function() { // or lamda.

      if (str[i] !== strJohn[0]) { // asumption of no empty strings, which incertain langauges are represented by \0\0 incase of other end condition optermization.
        return; //skip, basically goto end of parent block of brace code, this would allow for code after this doing a second string comparision to execute.
        // skip, break, continue should be parametised, which take in a number e.g skip(2), will skip to blocks.
        //*** alternative to return would be skip, which allows us not to use a anonmas function wrapper and overhead.***
      }

      let end = i + strJohn.length;
      
      // In javascript it looks like one is quite luck, as the comparison of arr[-1] == arr[-1] => undefined ===  is false, so there is no additioanl evaluation.
      // So I guess on needs check what happens in the arr access, but I am sure each access will be check string bounds anyways, so the only improvement here would be acess with null string terninator.
      // to get a speed up as one would have in c++, so I am guessing depending on the back altought the v8 is back by c++, could get a mabye not get one less if check.
      // typically if the input string 'str' is null terminated '\0' then this block of code wouldn't be needed.ONe see speed up of one less up front if statment, no branch prediction needed, typically only
      // when get near end of the string there would be a penalty for additional loop, increment, condition, if-break. for the posibly 90% of evaluations, improve branch prediction.
      // versus assignment, condition-execute.

      // if (end > str.length) { 
      //   end = str.length;
      // }    

      for (let j = 1, k = i + 1; k < end; j++, k++) {

        console.log(str[k] + ":" + strJohn[j]); // check iterations here for tetsing.
        if (str[k] !== strJohn[j])                 
          return;   // break;contiunue in sequence, or continue(2), in some circumstances, however, not if want futher cod eto run that is a results of positive match in other skip blocks.   
      }

      countJohn++;

    })();

    // Code that would typiclaly execute after the skip statment.
    //*** */:label-skip-alternative-matching-logic ***
    {
      end = Math.min(i + strMary.length, str.length);

      for (let j = 0, k = i; k < end; j++, k++) {

        const ch = str[k];

        if (ch !== strMary[j]) {    
          countMary--; // Many additional subtractions operations at a low level are required, can also result in greater mistakes and complicated code as assume all are matches, which for this case you can do.
          break;
        }
      }
    }

    {
      end = Math.min(i + strWasley.length, str.length);

      for (let j = 0, k = i; k < end; j++, k++) {

        const ch = str[k];

        if (ch !== strWasley[j]) {    
          countWasley--; //unessary computation, bnut require undoing computation, wasited cycles. 2X, also requires negative variables.
          break;
        }
      }

      countWasley++; // nessary sucessull computation.
      // if we get out the loop we would like to assume positive, but in this case,
      // we have to countWasley
    }
  }

  console.log("John:" + countJohn);
  console.log("Mary:" + countMary);
  console.log("Wasley:" + countWasley);

  return countJohn === countMary && countMary === countWasley;
}
console.log(johnMary("John"));
console.log(johnMary("John&Mary&Wasley\0"));

If I am following correctly these are all already possible with labels.

Proposal 1:

outerLoop: for (let i = 0; i < 10; i++) {
  for (let j = 0; j < 10; j++) {
    console.log(i + ":" + j + ",");
    if (j == 5) {
      continue outerLoop;
    }
  }
}

Proposal 2:

console.log('1');
test: {
  console.log('2');
  break test;
  console.log(`this won't run`);
}
console.log('3');

Proposal 3:

outerLoop: for (let i = 0; i < 5; i++) {
  for (let j = 0; j < 5; i++) {
    for (let j = 0; j < 5; i++) {
      console.log("K");
      break outerLoop;
    }
  }
}

Hi,

thank you for sharing that, was not where of that, because c/c++ specification labels are limited as I pulled the specification to be within block scope, as there are limitation of using goto can be used.

After testing this is my problem with the code and specification, which limits what is possible
never the less, this is already good to know, as in c continue is equivalent of goto, has not properly been integrated with for loop control like javascript has, however, still feel there is room for improvement, which gives us the correct ganulaity of control.
c++ breaking or goto the mostouter will have your program running indefinitely. as is different in meaning.

labelled object literal is great because break as if this was an early return function, but without having to nest an anonymous functions

  1. continue with a label, performs breaks and the last loop is a continuous behaviour, one still wants granularity of control here, because could have global scope variables, in which break, break, continue behaviour is not desired.

  2. break in a loop, stops execution and skips the final conditional check, incremental step as per normal.

  3. labels must be anywhere in the loop or outside section as long it now across function bounderies, obviously continue has the constraint of above the previous loop start. can't break to label brace section from outside the block scope.

4.skip, is required because break is basically only to parent block section label or an object literal bracet block, which allow for finer grain control.

  1. Chaning of break and continue statements, such that different behaviour of exiting multiple neasted loops can be achieved, so get program behaviour that one desires. continue 3 loops, out may not be want ones wants, with have more global variables.
mostLoop: for (let i = 0; i < 5; i++) {
    console.log("SkipContinue");
  /*  breakHere:{
        console.log("breakHere");
    }*/
    console.log("runCOntinue");
outerLoop: for (let j = 0; console.log("outerCondition") || j < 5; j++, console.log("outerLoopPosRepeatStep")) {
    
    console.log("outerinnerbefore");
    
    innerLoop: for (let k = 0; console.log("innerCondition") || k < 5; k++, console.log("innerLoopPosRepeatStep")) {
      console.log("K" + i + ":" + j + ":" + k);
//      continue innerLoop;
     //continue outerLoop;
      //break outerLoop;
      break mostLoop;
      console.log("SkipK");
    }
    console.log("outerinnerpost");
  }
}

test1: {
    console.log("test1");
    break test2
    console.log("test1postbreak");
}

test2: {
    console.log("test2")
}
  1. Break doesn't allow the trailing outerinnerpost to be executer if only breaking one level, where as break on its on will, this is a behaviour constence problem with non label break statement. Basically break or continue above at the label, the label does identifiy the loop to continue executing the break logic to, to is the point to continue form in code. break or continue should be the the point to which break or continue repeative are executed until the get to the label, which means that the outerinnerpost or outerpost, which is missing if example above, include here below would be executed.

mostLoop: for (let i = 0; i < 5; i++) {
    console.log("SkipContinue");
  /*  breakHere:{
        console.log("breakHere");
    }*/
    console.log("runCOntinue");
outerLoop: for (let j = 0; console.log("outerCondition") || j < 5; j++, console.log("outerLoopPosRepeatStep")) {
    
    console.log("outerinnerbefore");
    
    innerLoop: for (let k = 0; console.log("innerCondition") || k < 5; k++, console.log("innerLoopPosRepeatStep")) {
      console.log("K" + i + ":" + j + ":" + k);
      break innerLoop;
     //continue outerLoop;
      //break outerLoop;
      //break mostLoop;
      console.log("SkipK");
    }
    console.log("outerinnerpost");
  }
  console.log("outerpost");

}

I missed this, which is important, not just sets of logic being correctly for all permutations.

  1. The trailing outer post is what I would be using in alot of solutions assuming a true condition to a full loop run and not early exit, in which needs to be skipped. So I would use a break, to break my current loop, but execution of the trailing part statement outerinnerpost, iwth the break may and man't be warranted, one needs the break to take a label and optional flag or boolean to skip the outerinnerpost or to execute it, skip trailing loop code to get to parent loop code.

  2. continue outerLoop, the resulting innerloop outerinnerpost runs, which is not always wanted.

So for 6/7 one needs to be able to control if the trailing code is run, continue for mutiple levels and break normally.

So maybe break label(skipTailing)/break (skipTailing) and continue label(skipTrailing)/continue(skipTrailing), I am open to suggestion on this syntax, not fixed in stop, just the concept and functionality like at first, then how best integrate the terminology into the language.

I think that would get me the fine grained control that would be looking for with out any language compiler limitations, such one can write optimize high level code, near the control loop structure granularity of instruction or assemble would provide.

Please let me know you thoughts, I thinking this would finally get me all the permutations of control, required for improve solutions with less instructions eventually.

So basically this would be the solution using continue and labels, which I would say, avoid the range checking on the loop level and the calculation of the range end, by using null terminator on the search string, such that null !== undefined and extra if check to hand the last case, look for alternative here, in c++ need like a double character, but saving a few instructions here and there, if there are a lot of partial matches, then only checking one if statement so one less for each partial match.
I recon branch prediction should be better too, as main be on character matching and no branch prediction would be needed for increase performance at for loop level, since is no condition.

function johnMary(str) {

  str +="\0"; // add a sentinal, as john out of bounds is undefined, which is not equal to John.
  const strJohn = "John";

  let countJohn = 0;

    main:for(let i = 0; i < str.length; i++) {    

      match:for (let j = 0, k = i; true; j++, k++) {        
        if (str[k] !== strJohn[j]){                           
          if (strJohn[j] === undefined) {
            break;  
          }
          continue main;
        }        
      }

      countJohn++;
    }

    return countJohn
  }

  console.log(johnMary("John\0John\0"));

or less jumps..

function johnMary(str) {

  str +="\0"; // add a sentinal, as john out of bounds is undefined, which is not equal to John.
  const strJohn = "John";

  let countJohn = 0;

    main:for(let i = 0; i < str.length; i++) {    

      match:for (let j = 0, k = i; true; j++, k++) {        
        if (str[k] !== strJohn[j]){                                     
          if (strJohn[j] === undefined) {
            countJohn++;
          }
          continue main;
        }        
      }
    }

    return countJohn
  }
  console.log(johnMary("John\0John\0"));

For your particular example I would imagine that the highly optimised RegularExpression libraries that most JavaScript engines use would be hard to beat, even with added syntax for optimising for loops.

const johns = /John/g;
function johnMary(str) {
  johns.lastIndex = 0;
  let count = 0;
  while (johns.test(str)) ++count;
  return count;
}

Ja this all arows out of see a different way to solve a different problem, which continue label stuff and other hacks above, which felt would be very hand to have in future, as those solutions where much simpler, just attempted to look at applying it to other problems like the string version.

There problem would be a tag more overhead, but depends as optimization and match 4 characters and things in the compilation of that statement.

Never the less thanx for highlight the continue label and break label, would still like to see improve controlability for more than two neasted loops tough.

well i am pretty glad I have new way looping and kicking out now for different problems, however, this is limited to javascript language that I know of right now, with out checking and also has few limitations, but see what one can improve other solution of with.

What exactly is your use case here? Your example given here could literally just be this, if you wanted to avoid regular expressions:

function johnMary(str) {
  let count = 0
  for (let i = str.indexOf("John"); i >= 0; i = str.indexOf("John", i)) {
    count++
  }
  return count
}