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 what I tried to do:

Scan[Function[x,
  Scan[Function[y,
    If[y == 2, Return[]];
    (* Do something useful *) Print[y]],
   x]],
 {{1, 2, 3}, {4, 5, 6}}]

My intention was that the Return[] exited from the innermost enclosing pure function (having the parameter y). Instead, it terminated execution of the innermost enclosing Scan and proceeded to the next iteration of the outermost Scan.

1 4 5 6

The documentation for Return says:

Return exits only the innermost construct in which it is invoked

I do not see why the innermost Scan is considered the innermost enclosing construct here. If, CompoundExpression and Function look like more inner constructs.


Question 1: Could you give a more clear explanation of what precisely Return does?


After I realized that Return does not do what I want here, I looked for workaround, and found several ones:

(a) I can restructure the body of the innermost pure function:

Scan[Function[x,
  Scan[Function[y,
    If[y != 2,
     (* Do something useful *) Print[y]]
    ],
   x]],
 {{1, 2, 3}, {4, 5, 6}}]

In this case it looks straighforward, but becomes messy if I have more nested control flow operators and multiple points where I might need to exit.

(b) I can use infamous Label and Goto constructs:

Scan[Function[x,
  Scan[Function[y,
    Module[{exit},
     If[y == 2, Goto[exit]];
     (* Do something useful *) Print[y];
     Label[exit];
     ]], 
    x]],
 {{1, 2, 3}, {4, 5, 6}}]

(c) I can use Throw and Catch constructs:

Scan[Function[x,
  Scan[Function[y,
    Module[{exit},
     Catch[
      If[y == 2, Throw[Null, exit]];
      (* Do something useful *) Print[y],
      exit]]],
   x]],
 {{1, 2, 3}, {4, 5, 6}}]

Question 2: Which of them would you prefer? Or can you suggest a better way to do this?

share|improve this question
add comment

3 Answers

up vote 9 down vote accepted

You can specify the evaluation of which construct should be stopped by Return by providing the second argument (undocumented?). For example,

Scan[Function[x,
  Module[{},
   Print[x];
   Return[$Failed, Module];
   Print[-x]]],
 {1, 2, 3}]

or

Scan[Function[x,
  Print[x];
  Return[$Failed, CompoundExpression];
  Print[-x]],
 {1, 2, 3}]
share|improve this answer
3  
It isn't documented under Return but it is here: Return::nofunc –  Chris Degnen Dec 5 '13 at 17:11
add comment

It's hard to reply without larger context, but if you are not restricted to use pure functions, then one option would be to use the pattern-defined overloaded function instead:

ClearAll[fun];
fun[2] := Null;
fun[x_] := ((*Do something useful*)Print[x])

Then, you just write:

Scan[Function[x, Scan[fun, x]], {{1, 2, 3}, {4, 5, 6}}]

In fact, you can as well define fun at run-time, if you need.

As to Return, I can recommend this, and particularly this discussions for more details on how it works.

share|improve this answer
add comment

I would use Catch and Throw if pressed to choose, without the 'exit' :

Scan[Function[x,
  Scan[Function[y,
    Catch[If[y == 2, Throw[Null]];
     (*Do something useful*) Print[y]]
    ],
   x]],
 {{1, 2, 3}, {4, 5, 6}}]

or simply,

Scan[Function[x,
  Scan[Function[y,
    If[y == 2, Null,
     (*Do something useful*) Print[y]]
    ],
   x]],
 {{1, 2, 3}, {4, 5, 6}}]
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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