Re: Documentation of Return is a little confusing?

*To*: mathgroup at smc.vnet.net*Subject*: [mg113451] Re: Documentation of Return is a little confusing?*From*: Leonid Shifrin <lshifr at gmail.com>*Date*: Fri, 29 Oct 2010 06:28:26 -0400 (EDT)

Nasser, Return seems to be not the most well-designed command in Mathematica, to say the least. To me, it looks more like a hack, and the more such use cases as yours I see the more evidence it gives to support this. There have been several threads on Return which may interest you. Here is one: http://groups.google.com/group/comp.soft-sys.math.mathematica/browse_thread/thread/12419727c096caad The common wisdom seems to be to avoid using Return. Regarding your case: one way to make it work is to use the second (undocumented) form of Return where it takes as a second argument a name of the construct it should break from: Clear[f]; f[] := Module[{i}, For[i = 1, i <= 2, i++, {If[True, Return[True, Module]]} ]; False] f[] True However, the behavior of single-argument return in your example looks like a bug to me - it indeed seems to contradict the documentation. One other way to fix it in this particular case: add UpValues for Return specifically for lists: Unprotect[Return]; Return /: List[left___, x_Return, right___] := Return[x]; Protect[Return]; Now your original code will also work as intended, but this is a point solution, so the first one is probably better if you really have to use Return. Better still, if you can rewrite your code to not use it at all. Regards, Leonid On Thu, Oct 28, 2010 at 12:27 PM, Nasser M. Abbasi <nma at 12000.org> wrote: > ?Return says (under More information) > > "Return[expr] exits control structures within the definition of a > function, and gives the value expr for the whole function." > > Notice, where it says "gives the value expr for the whole function", > again, it says "__whole function__" ! > > Therefore, on writing the following function, and calling it using f[], > what do you expect the result to be? > > ---------------- > f[]:=Module[{i}, > > For[i=1,i<= 2,i++, > { > If[True,Return[True]]; > } > ]; > > False > ] > --------------------- > > On reading the help, one expects True to be resturned, right? but no: > > In[4]:= f[] > Out[4]= False > > Not only is the above confusing enough, but removing the {} after For > changes the behaviour > > ----------------- > In[6]:= f[]:=Module[{i}, > > For[i=1,i<= 2,i++, > If[True,Return[True]]; > ]; > > False > ] > -------------------- > > Now, > > In[7]:= f[] > Out[7]= True > > Ok, now before someone screams at me telling all the above can be easily > explained by reading what it says under "possible issues": > > "Return exits only the innermost construct in which it is invoked" > > I do know this. And I do know that the above explains all. > > But my point is that the documentation of Return is conflicting with > itself. > > In one place, it says > > "gives the value expr for the whole function" > > and in the other place it says > > "Return exits only the innermost construct in which it is invoked" > > The above 2 statments, at least for the casual user, can not mean the > same thing? Or Am I not seeing something very deep here? > > --Nasser > > --20cf30025852a6ef850493b2e2ff Content-Type: text/html; charset="ISO-8859-1" Content-Transfer-Encoding: quoted-printable X-Sun-Content-Length: 4291 Nasser,<div><br></div><div>Return seems to be not the most well-designed= command in Mathematica, to say</div><div>the least. To me, it looks more l= ike a hack, and the more such use cases as yours I </div><div>see the mor= e evidence it gives to support this. There have been several threads </di= v> <div>on Return which may interest you. Here is one:</div><div><br></div><di= v><a href="http://groups.google.com/group/comp.soft-sys.math.mathematica/= browse_thread/thread/12419727c096caad">http://groups.google.com/group/comp.= soft-sys.math.mathematica/browse_thread/thread/12419727c096caad</a></div> <div><br></div><div>The common wisdom seems to be to avoid using Return. = </div><div><br></div><div>Regarding your case: one way to make it work is t= o use the second (undocumented)</div><div>form of Return where it takes as = a second argument a name of the construct it should break</div> <div>from:</div><div><br></div><div><div>Clear[f];</div><div>f[] :=</div>= <div> Module[{i},</div><div> For[i = 1, i <= 2, i++,</div><di= v> {If[True, Return[True, Module]]}</div><div> ];</div><div> = False]</div><div> <br></div><div>f[]</div></div><div><br></div><div>True</div><div><br></div>= <div>However, the behavior of single-argument return in your example looks = like </div><div>a bug to me - it indeed seems to contradict the documenta= tion. One other way </div> <div>to fix it in this particular case: add UpValues for Return specificall= y for lists:</div><div><br></div><div><div>Unprotect[Return];</div><div>Ret= urn /: List[left___, x_Return, right___] := Return[x];</div><div>Protect[= Return];</div> </div><div><br></div><div>Now your original code will also work as intended= , but this is a point solution,</div><div>so the first one is probably bett= er if you really have to use Return. Better still,</div><div>if you can rew= rite your code to not use it at all.</div> <div><br></div><div>Regards,</div><div>Leonid</div><div><br><br><div class= ="gmail_quote">On Thu, Oct 28, 2010 at 12:27 PM, Nasser M. Abbasi <span d= ir="ltr"><<a href="mailto:nma at 12000.org">nma at 12000.org</a>></span= > wrote:<br> <blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1p= x #ccc solid;padding-left:1ex;">?Return says (under More information)<br> <br> "Return[expr] exits control structures within the definition of a<br> function, and gives the value expr for the whole function."<br> <br> Notice, where it says "gives the value expr for the whole function&quo= t;,<br> again, it says "__whole function__" !<br> <br> Therefore, on writing the following function, and calling it using f[],<br> what do you expect the result to be?<br> <br> ----------------<br> f[]:=Module[{i},<br> <br> For[i=1,i<= 2,i++,<br> {<br> If[True,Return[True]];<br> }<br> ];<br> <br> False<br> ]<br> ---------------------<br> <br> On reading the help, one expects True to be resturned, right? but no:<br> <br> In[4]:= f[]<br> Out[4]= False<br> <br> Not only is the above confusing enough, but removing the {} after For<br> changes the behaviour<br> <br> -----------------<br> In[6]:= f[]:=Module[{i},<br> <br> For[i=1,i<= 2,i++,<br> If[True,Return[True]];<br> ];<br> <br> False<br> ]<br> --------------------<br> <br> Now,<br> <br> In[7]:= f[]<br> Out[7]= True<br> <br> Ok, now before someone screams at me telling all the above can be easily<br= > explained by reading what it says under "possible issues":<br> <br> "Return exits only the innermost construct in which it is invoked"= ;<br> <br> I do know this. And I do know that the above explains all.<br> <br> But my point is that the documentation of Return is conflicting with<br> itself.<br> <br> In one place, it says<br> <br> "gives the value expr for the whole function"<br= > <br> and in the other place it says<br> <br> "Return exits only the innermost construct in which it is invoked"= ;<br> <br> The above 2 statments, at least for the casual user, can not mean the<br> same thing? Or Am I not seeing something very deep here?<br> <font color="#888888"><br> --Nasser<br> <br> </font></blockquote></div><br></div> --20cf30025852a6ef850493b2e2ff--