Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Here is simplified version of my code that exhibits the behavior troubling me:

testFn[] := (
  Do[
   Print[i];
   If[i > 3, Print["triggering result for true"]; Return [100]]
   , {i, 1, 5}];
  Return[200];
  )

testFn[]
1
2
3
4
triggering result for true
200

Intuitively, once i is bigger than 3, it should evaluate the 2nd argument of the If and exit testFn, returning 100. However, although the 2nd argument of the If statement is getting evaluated, the function does not exit until it hits the Return[200].

I kind of guessed what might be the problem. The Return[100] is just exiting the Do, which seems to be confirmed by doing:

testFn[] := (
  a = Do[
    Print[i];
    If[i > 3, Print["triggering result for true"]; Return [100]]
    , {i, 1, 5}];
  Print["a=" <> ToString[a]];
  Return[200];
  )

1
2
3
4
a=100
triggering result for true
200

If this is indeed what's happening, how can I make my code actually return from and exit testFn?

share|improve this question

marked as duplicate by m_goldberg, bobthechemist, Michael E2, ubpdqn, RunnyKine Jul 11 at 1:32

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

1  
Do Return[100, Module] Not just Return[100] see mathematica.stackexchange.com/questions/44585/… for more information –  Nasser Jul 10 at 17:42
    
Take a look here: mathematica.stackexchange.com/questions/29353/… –  Szabolcs Jul 10 at 19:00

1 Answer 1

Nasser in his comment is referring (somewhat cryptically) to an undocumented second argument of Return. You would use it this way.

test1[] :=
  Module[{},
    Do[Print[i]; If[i > 3, Print["i > 3"]; Return[100, Module]], {i, 1, 5}];
    200]

However, I prefer to avoid undocumented stuff, so I recommend

test2[] :=
  Catch[
    Do[Print[i]; If[i > 3, Print["i > 3"]; Throw[100]], {i, 1, 5}];
    200]
share|improve this answer
    
While I agree in general about the undocumented functionality, I think that in this particular case the use of Return with a second argument is a better solution. It is very unlikely that this feature will be discontinued, AFAICT. –  Leonid Shifrin Jul 10 at 23:55
    
it is documented, but as WReach showed, it is hidden here reference.wolfram.com/language/ref/message/Break/nofunc.html The second argument is used here to specify that the return should be from the enclosing Module: In addition, I am not sure that using Throw/Catch to control programming logic is a good way to do things. These are meant to be used for exceptional cases, not normal flow. But this is for another subject :) –  Nasser Jul 10 at 23:56
    
Instead of Throw/Catch you could equivalently use Reap/Sow (with some list logic on top). –  evanb Jul 11 at 0:06
    
@Nasser. As someone who spent many years coding in Common Lisp, I don't share your view of Catch and Throw as being to restricted to handling exceptions, although that is certain a good use of them. I admit you have found (obscure) documentation for Return with a 2nd arg, but you can hardly expect the average Mathematica to be aware of it. –  m_goldberg Jul 11 at 0:13

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