0
|
9551 Views
|
8 Replies
|
6 Total Likes
View groups...
Share
Share this post:
GROUPS:

# Return[] in functions

Posted 10 years ago
 Hello, in this example of code: f1[x_] := Return[x + 1]; f2 := Function[{x}, Return[x + 1]]; f1[1] returns "2", but f2[2] returns "Return[2]". Why doesn't the Return[] operator work correctly in the second function?
8 Replies
Sort By:
Posted 10 years ago
 OK, so these two ways of functions declaration aren't equivalent. This is exactly true: these are completely different constructs. Strictly speaking, there are no "function declarations" in Mathematica (in the C language sense). Mathematica has global replacement rules and pure functions. When you evaluate f[x_]:=x^2 you define a global replacement rule which replaces each occurrence of an expression which matches f[x_] with x^2.When you evaluate f=#^2& or f=Function[x,x^2] you define a global replacement rule which replaces each occurrence of f with Function[#,#^2] or Function[x,x^2] accordingly. The Function has its own logic of evaluation.
Posted 10 years ago
 Ah yes, code that takes code in its argument. One might like to think that things like that are exceptional cases, but that isn't necessarily so for many of the things one might want to do with Mathematica. So this sort of thing is very worth remembering when one finds behavior that seems "buggy" in code that one has written that processes code--and such cases will invariably have Hold* attributes or make use of Unevaluated and things like that....
Posted 10 years ago
 Well, that has its dangers too.Consider this toy example: In[5]:= SetAttributes[f, HoldAll] f[x_] := Catch@Module[{}, If[x < 0, Throw[$Failed]]; Sqrt[x]] In[7]:= f[-1] Out[7]=$Failed In[8]:= f[2] Out[8]= Sqrt[2] In[9]:= f[Throw[boo]; 2] Out[9]= boo The same caveat applies to Sow/Reap.This can be fixed by using a (private) tag with Throw and Catch (or Sow and Reap).
Posted 10 years ago
 Actually I always use f[...] := Catch@Module[{...}, ... If[error, Message[f::err]; Throw[$Failed]]; ... If[otherError, Message[f::err]; Throw[$Failed]]; ... result ] in those cases ;-) . Part of the reason is just habit, but also it allows me to control exactly where the Throw gets caught without any ambiguity. And one can use tags in appropriately palced Throws and Catches if a more complex logic is needed.
Posted 10 years ago
 This is some useful reading: http://mathematica.stackexchange.com/q/29353/12@DavidWhile Return is very rarely needed, I think it's quite useful in situations like f[...] := Module[{...}, ... If[error, Message[f::err]; Return[$Failed]]; ... If[otherError, Message[f::err]; Return[$Failed]]; ... result ] (since this can be such a common pattern)
Posted 10 years ago
 And a more general statement is never to use Return anywhere in your Mathematica programs. (Nor use Label, Goto, or other ancient approaches to flow control--they are in Mathematica for those who are coming from old programming paradigms, but are strongly recommended against.) If you need to leave a program flow prematurely use Throw and Catch or in some cases Sow and Reap. Remember that Mathematica returns the last evaluation in a CompoundExpression (i.e., a sequence of commands separated by semicolons) so long as the final command is not ended with a semicolon.
Posted 10 years ago
 OK, so these two ways of functions declaration aren't equivalent.
Posted 10 years ago
 Actually f2[2] returns "Return[3]". Don't use "Return" in a pure function, write f2 := Function[{x}, x + 1]; Now f2[2] returns 3.
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments