How could I Break from only the innermost loop in a



I get the desired behaviour if I use


but this hard to utilize because the number of loops in my program is not fixed, and therefore I normally create a Table the iterator specs with a function myiterators[n] where n is the number of loops, and use


If stuff contains a Break here, it breaks all n loops... Instead of only generating the iterators, I could of course generate the full Do[Do[... structure using Fold or similar, but this does not seem like the best way.


In my case, the function myiterators contains a call to a compiled function to evaluate the upper limits of the iterators. This precludes the use of Evaluate[Sequence@@...] since Evaluate forces the evaluation of the compiled function before the iterators aquire values in mulitDo. My solution was to use

   multiDo2] = {"LocalVariables" -> {"Table", {2, Infinity}}};
SetAttributes[multiDo2, HoldAll];
multiDo2[code_, {rest___, iter_}] := 
  multiDo2[Do[code, iter], {rest}];
multiDo2[code_, {}] := code;

and call it with


Works like a charm!

  • 2
    $\begingroup$ Use Catch & Throw instead of Break. $\endgroup$ May 14, 2015 at 16:01
  • $\begingroup$ @ChrisDegnen, how? Catch[Do[If[j > 7, Throw[Null]]; Print[{i, j}], {i, 9}, {j, i + 1, 10}]] never reaches i>1... $\endgroup$ May 14, 2015 at 16:04
  • $\begingroup$ See Catch - Generalisations & Extensions for use of tags. $\endgroup$ May 14, 2015 at 16:07

1 Answer 1


I think this is a good case for a simple code generation. Here is one way to generate multiple Do in a macro-like fashion:

SyntaxInformation[multiDo] = {"LocalVariables" -> {"Table", {2, Infinity}}};
SetAttributes[multiDo, HoldAll];
multiDo[code_,  rest___, iter_] := multiDo[Do[code, iter], rest];
multiDo[code_] := code;

Basically, multiDo is a new language construct. It constructs the nested Do code at run-time, without evaluating the body, and then evaluates the code, after it has been fully constructed. Notice that (as MichaelE2 pointed out in comments), the outer-most iterator in the multiple-iterator syntax becomes the inner-most one in the generated code.

Here is an example:

sum = 0;
multiDo[If[i > j, Break[], sum += i], {j, 10}, {i, 10}];

(* 220 *)

In this case, similar result can be accomplished by

sum = 0;
Do[sum += i, {i, 10}, {j, i, 10}]

(* 220 *)

but in general, one can't easily reduce the multiDo to a simple Do with multiple iterators.

  • $\begingroup$ Doesn't the normal order of iteration have the last iterator be the inside iterator? E.g. multiDo[code_, rest___, iter_] := (* same *)? $\endgroup$
    – Michael E2
    May 14, 2015 at 16:27
  • $\begingroup$ @MichaelE2 You are right, nicely spotted! Will edit. $\endgroup$ May 14, 2015 at 16:30
  • 2
    $\begingroup$ @LeonidShifrin, thanks for teaching me this way of doing it. I discovered that Do[Catch[stuff;Throw[something]],i1spec,i2spec,...] also seems to work. Do you know why? I don't understand how Catch somehow is outside only the innermost loop. $\endgroup$ May 14, 2015 at 16:40
  • $\begingroup$ @MariusLadegårdMeyer Indeed, it works, although it's not obvious at all that it should. I can well imagine an implementation of Do[body, iter1, ..., itern], which would satisfy all the Do specs but where this won't work. So, unless I am missing something, this means relying on hidden deatails or an implementation (which one also often does, but which is generally considered not to be a great practice). $\endgroup$ May 14, 2015 at 17:20
  • 1
    $\begingroup$ Another advantage of the method I proposed is that it won't be too hard to get it into Compile, if needed. $\endgroup$ May 14, 2015 at 17:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.