Have I missed something or is there no built-in which mimics the behaviour of do ... while loop?

I am looking for a construct that evaluates procedure once and then repeatedly evaluates it while test is not fulfilled.

I'm ended up using:

While[procedure; test, {}]

But clearly the second argument is redundant, so I have a feeling that I'm missing something. Maybe not, but I just want to be sure :)


closed as off-topic by Mr.Wizard Mar 19 '14 at 9:56

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "This question arises due to a simple mistake such as a trivial syntax error, incorrect capitalization, spelling mistake, or other typographical error and is unlikely to help any future visitors, or else it is easily found in the documentation." – Mr.Wizard
If this question can be reworded to fit the rules in the help center, please edit the question.

  • 2
    $\begingroup$ While[(procedure;test)] - parens. optional, makes it clear I think... $\endgroup$ – ciao Mar 18 '14 at 10:06
  • 2
    $\begingroup$ Not sure how a compound statement is abuse...first example under scope in the docs does it in compact form. $\endgroup$ – ciao Mar 18 '14 at 10:12
  • $\begingroup$ @rasher Agree, abuse is not a good word. I mean, docs say first arg is a test which may be missleading and the example you are referring to is ok but formed in easy-to-overlook way. Especially for new users. I think it could be an useful topic for future visitors. $\endgroup$ – Kuba Mar 18 '14 at 10:17
  • 1
    $\begingroup$ @rasher To the conclusion: I don't think there should be a separate function. My goal is to show to future beginners :), who may have doubts similar to mine in the past, that this is the way. $\endgroup$ – Kuba Mar 18 '14 at 10:29
  • 1
    $\begingroup$ DoWhile exists as a function and as a macro rule in GeneralUtilities` . $\endgroup$ – Karsten 7. Oct 5 '16 at 6:41

While While[procedure; test] works, it looks very similar to While[test, procedure]. The only difference is ; vs ,. While is not the most commonly used construct, so when used like this there's a high chance of misunderstanding/misreading.

If readability/reliability is a concern (for example a collaboratively developed published package), I'd use the longer but clearer

  If[Not[test], Break[]]

The only argument here is readability and "defensive programming" (extra effort to avoid accidental problems). Readability is subjective. If you are the only person who writes/reads the code and you get used to this use of While (and thus always pay special attention to the , vs ;) then this argument doesn't apply.


Why not write your own and place it in your init.m file?

SetAttributes[DoWhile, HoldAll];

DoWhile[procedure_, test_] := While[procedure; test]
  • $\begingroup$ One point against is that the code with it posted on SE requires explanation :) $\endgroup$ – Kuba Mar 18 '14 at 16:24
  • $\begingroup$ @Kuba what do you mean? I'm afraid I don't understand. $\endgroup$ – Chip Hurst Mar 18 '14 at 18:36
  • $\begingroup$ If I put that in my init file and then post the answer here, using this function, I will have to add definition :) $\endgroup$ – Kuba Mar 18 '14 at 18:37
  • $\begingroup$ Oh haha, got it! $\endgroup$ – Chip Hurst Mar 18 '14 at 18:37

Here's another way to write your own:

SetAttributes[doWhile, HoldAll];    
doWhile[expr_, test_] := CompoundExpression[expr, While[test, expr]]

Or just:

doWhile[expr_, test_] := (expr; While[test, expr])

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