MathGroup Archive 1998

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Return inside Do, For and While



> I am going through the Power Programming book by Wagner and have a
> question about Return[value].
> 
> According to the documentation, it is supposed to cause a "function" to
> return a value.  I have always used it to exit and return a value from
> a Module or With.  Because I almost never use Do, For or While except
> when following a textbook, I had never tried to use Return from inside
> a loop.
> 
> For example, consider the following code that tests a list of integers
> to see if they are all odd:
> 
> allOdd[x_List]:=Module[{i=1},
> 
>         Do[If[!OddQ[x[[i]]],
>               Return[False]];
>             i++,
>         {Length[x]}];
> 
>                 Return[True]]
> 
> This function returns True no matter what the list is.  Consider the
> following modification:
> 
> allOdd[x_List]:=Module[{i=1},
>         If[!Do[If[!OddQ[x[[i]]],
>         Return[False]];
>         i++,
>     {Length[x]}],
> Return[False]];
> 
>                 Return[True]]
> 
> This makes it clear that Wolframs definition of a "function" includes
> loops (Do, While, For).
> 
> Does anyone know what other built in objects qualify as "functions" for
> purposes of using Return?


   Return[expr] is used to return expr from a function that you have 
   defined, or to exit from an enclosing CompoundExpression, Do, For,
   Scan, or While expression. 

See that web page for additional notes and examples.

If you need to transfer program control to an unambiguous place outside
of a function, the best way to do that is with Throw and Catch.  The
Catch function allows you to specify where the Throw function should
throw to.

In contrast with procedural languages, where "return" pops one level up
the subroutine return stack, there isn't an intuitively obvious place
in a functional programming language for "return" to return.  This
ambiguity is addressed in functional programming languages (such as
various dialects of LISP) by including heuristics to try to guess the
intended return destination, or by providing language constructs (such
as labeled blocks or catch-like functions) that allow for specifying
the return destination.

In Mathematica you can use Throw and Catch:

In[1]:= allOdd[x_List]:= Catch[Module[{i=1},
                 Do[If[!OddQ[x[[i]]],
                       Throw[False]];
                     i++,
                 {Length[x]}];
                         Throw[True]]]

In[2]:= allOdd[{1,3,6,11}]

Out[2]= False

or you could add a second level of Return (to return both from the Do
loop and from your function):

In[3]:= allOdd[x_List]:=Module[{i=1},
                 Do[If[!OddQ[x[[i]]],
                       Return[Return[False]]];
                     i++,
                 {Length[x]}];
                         Return[True]]

In[4]:= allOdd[{1,3,6,11}]

Out[4]= False

In[5]:= allOdd[{1,5,9}]

Out[5]= True

or you could use the two-argument form of Return to specify that the
Return should return from the enclosing Module:

In[6]:= allOdd[x_List]:=Module[{i=1},
                 Do[If[!OddQ[x[[i]]],
                       Return[False, Module]];
                     i++,
                 {Length[x]}];
                         Return[True, Module]]

In[7]:= allOdd[{1,3,6,11}]

Out[7]= False

In[8]:= allOdd[{1,5,9}]

Out[8]= True

but with just Return[False] the behavior will depend on the implied
return destinations that have been programmed into the system, which
may not be what you had expected.  The implied return destinations that
are used in Mathematica match the expected destination perhaps
ninety-five percent of the time (and I personally don't know how to to
do any better than that), but if you need to return to an unambiguous
place, you might want to try Throw and Catch, or some other
construction.

Dave Withoff
Wolfram Research



  • Prev by Date: Re: Newbe: Wave equation
  • Next by Date: No Subject
  • Prev by thread: Return inside Do, For and While
  • Next by thread: Re: Return inside Do, For and While