Mathematica has the While
function which is very convenient when we need to process some code until the attainment of a certain state (identified with a condition). Personally, I also like very much the Loop-Until approach.
An advantage of the Loop body Until condition is that the body being performed first, it is not necessary to set initial values to the variables being tested in condition. In While
, all the variables must be set so that the preliminary test can return a value.
I have this definition below but would like to know if there are more efficient ways to define a Loop.
Loop[body_, test_] := Block[{}, body; While[! test, body]]
SetAttributes[Loop, HoldAll]
Edit
With the nice comments of everyone, I updated the code so that a MaxIterations option can be given, and usage and error messages are provided:
Unprotect[Loop];
Loop::usage = "Loop[body, test] performs body then verify test until test returns True. Loop[body, test, MaxIterations-> i] sets a maximal number of iterations (default infinity).";
Loop::maxiter = "Maxiterations `1` reached. Aborting...";
Loop[body_, test_, opt___] := Block[
{res, currenti = 1, maxi = MaxIterations /. {opt} /. Options[Loop]},
body;
While[(!test) && (currenti<maxi),
res = body;
If[maxi == ++currenti, Message[Loop::maxiter, currenti]; Abort[]]
];
res
]
SetAttributes[Loop, HoldAll]
Options[Loop] = {MaxIterations -> Infinity};
Protect[Loop];
Here are two examples
n = 1;
Loop[Print[n]; ++n, n > 4]
n = 1;
Loop[Print[n]; ++n, n > 4, MaxIterations -> 2]
keepRunning = True; While[keepRunning, ...... If[condition,keepRunning=False]]
. Notice there is no no need to doBreak[]
now. This will run one time at least. This is how we used to program in the good old days :) $\endgroup$