5
$\begingroup$

I need to test some complicated conditions to calculate a Return value. But MMa doesn't let you Return[] from anywhere the way C++ does. The structure of my Module is similar to this:

foo[x_] := Module[{}, Do[ If[x == (n^2), Return[0]]; If[x == (n^4), Return[1]], {n, 1, 5}]; Return[2]]; 

If Return[] actually Return'd, foo[4] would return 0, but instead it returns 2.

Is there a way to do a return from an arbitrary place in the code?

I know that effete programmers will dislike my program structure, but I'm asking how to force the Return[], not how to restructure the program.

$\endgroup$
3
  • $\begingroup$ See the doc page of Return under Possible Issues. Due to how expressions are evaluated, "function call boundaries" are not as clear as in C++. $\endgroup$ Commented Apr 21, 2015 at 18:59
  • 2
    $\begingroup$ Related: (29353), (6815), (18519), (58059) $\endgroup$ Commented Apr 21, 2015 at 19:12
  • $\begingroup$ @Mr.Wizard yes, a well traveled topic. $\endgroup$ Commented Apr 21, 2015 at 19:14

2 Answers 2

6
$\begingroup$

As pointed out in the comments, Return only exits from the inner most construct. So, even though foo[4] hits the True clause in the first If statement, that only exits Do. Instead of using Return, use Throw/Catch, e.g.

bar[x_] := Module[{$myTag}, Catch[ Do[ If[x == (n^2), Throw[0, $myTag]]; If[x == (n^4), Throw[1, $myTag]] , {n, 1, 5} ]; Throw[2, $myTag] , $myTag ] ]; 

Note, I use $myTag to insulate Catch against other throws. Then,

bar /@ {1, 2, 4, 7, 8, 16} (* {0, 2, 0, 2, 2, 1} *) 
$\endgroup$
6
$\begingroup$

If your Module were not inert you could use the second parameter of Return as follows:

foo[x_] := Module[{n}, Do[ If[x == (n^2), Return[0, Module]]; If[x == (n^4), Return[1, Module]], {n, 1, 5} ]; Return[2] ] foo[4] 
0 

Alternatively you could Return to CompoundExpression if you eliminate it from within the Do loop:

foo[x_] := ( Do[ {If[x == (n^2), Return[0, CompoundExpression]], If[x == (n^4), Return[1, CompoundExpression]]}, {n, 1, 5} ]; Return[2] ) foo[4] 
0 

For a more complete explanation see:

$\endgroup$
9
  • $\begingroup$ That's why Return[0, Module] didn't work when I tried it. +1 $\endgroup$ Commented Apr 21, 2015 at 19:32
  • 1
    $\begingroup$ @rcollyer I'll admit it threw me at first too but I avoid null Module constructs like the plague so I hadn't come across it before. $\endgroup$ Commented Apr 21, 2015 at 19:34
  • $\begingroup$ I see them occasionally, mostly on here, though, as most feel the need to put some sort of scoping construct around code when simple parentheses will do. $\endgroup$ Commented Apr 21, 2015 at 19:36
  • $\begingroup$ What does "inert" mean in this context? $\endgroup$ Commented May 1, 2015 at 5:02
  • 1
    $\begingroup$ @Mr.Wizard, I suspect that a response you'd find useful is a bit beyond my MMa sophistication. I couldn't make sense of rcollyer's Answer about tags at all. I got your code suggestion to Return stuff the way I wanted it to, but I still didn't understand your clarification about inert Modules or why my Module was inert or what the CompoundExpression thing did. I asked my Aug 11 question in the Comment above because there's SO much in MMa's design that seems to senseless and needlessly complicated to me that I wonder if there's some overarching method to WR's madness that I'm just not seeing.. $\endgroup$ Commented Aug 15, 2015 at 20:25

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.