RE: "f[x_]:= 2 x" vs. "f = 2 #&"
- To: mathgroup at smc.vnet.net
- Subject: [mg16467] RE: [mg16365] "f[x_]:= 2 x" vs. "f = 2 #&"
- From: "Ersek, Ted R" <ErsekTR at navair.navy.mil>
- Date: Sat, 13 Mar 1999 02:22:03 -0500
- Sender: owner-wri-mathgroup at wolfram.com
Kevin Jaffe wrote: ------------------------- What significant differences exist among the following three ways to define a function f: f[x_]:= 2 x f = Function[x, 2 x] f = 2 #& Are there situations where one form is better than the others? -------------------------- Since you name each function (f) there is little difference except possibly timing performance, but there can be other factors involved for pure functions that aren't named. Consider the lines below. In[1]:= f[x_]:=2 x Using the convention above we can map (f) over a list with the next line. Using this approach we have to use a variable for the name of the function. In[2]:= Map[f,{a,b,c}] Out[2]= {2 a,2 b,2 c} We can use a pure function to do the same thing in the next line. This has the advantage that we don't have to use a variable to name the function. It also has the advantage that it's very concise. One disadvantage is that it looks like Greek to a newbee. In[3]:= Map[2#&,{a,b,c}] Out[3]= {2 a,2 b,2 c} The FullForm of (2#&) is more or less Function[2#] This almost the same as Function[x, 2x] ------------------------------- Suppose you are writing a program with the form func[x_]:= (*****algorithm*****) and (algorithm) has to make a function that will be used at later stages of (algorithm). It's illegal to use patterns on the right side of a definition. So (algorithm) can't make the function with the approach f[x_]:= 2 x It also can't make the function with the approach f[x_]= 2 x Instead (algorithm) must make the function with one of the following f=2#& f=Function[2#] f=Function[x,2x] So when would you need to do this? One such case is the function below. This function will plot a function using arbitrary precision arithmetic to sample the function. This is useful in special cases when a function must be sampled using arbitrary precision arithmetic. (***********) PrecisionPlot[f_,{x_,xmin_,xmax_},opts___?OptionQ]:= Module[{g,h}, (g=Function[f/.x->#]; h=(g[SetPrecision[#,17]]&); Plot[h[x],{x,xmin,xmax},opts] ) ] (***********) As far as I can tell there was no way to get PrecisionPlot working without using a pure function as I do with g=Function[f/.x->#] For an extensive discussion of this program down load (PrecisionPlot.nb) at http://www.mathsource.com/Content/Enhancements/Graphics/2D/0209-887 This is a brand new MathSource item I submitted. -------------------- Now suppose you need to define a function with the attributes Flat, Orderless. You could use the approach: SetAttributes[f,{Flat,Orderless}]; f[x__]:= (*****expr******) Now what if you want to avoid giving this function a name, or if you absolutely had to use pure function as I did with PrecisionPlot. In this case you can't use the short hand notation ( as in 2#& ). Instead you can use the following Function[##, (*****expr*****), {Flat,Orderless} ] Note, ## stands for all arguments given to the function. As a concrete example where this can be used Dave Withoff once helped me debug some code that will force StandardForm to use the equivalent of MatrixForm to format a matrices. The code is given below. (*********************) MakeBoxes[m_?(Function[t, MatrixQ[Unevaluated[t]]&&( t=!={{}} ), HoldAll]), form_]:= RowBox[{"(", GridBox[ Map[Function[t, MakeBoxes[t, form], HoldAll], Unevaluated[m],{2}]], ")"}] (*****************) Notice the part that says; Function[t, MakeBoxes[t, form], HoldAll] This is a function that wasn't given a name. Apparently you don't have to have the attributes in a list if there is only one of them. However, this isn't indicated in the documentation. -------------------------- Section 2.6.4 of the Mathematica Book covers some advanced aspects of variable scoping inside Function. I don't think the points discussed in this section apply to constructs like ( f[x_]:=2x ) However, I still need to get a good handle on that section of the book. If you paste the line below into a notebook you will have a hyperlink to section 2.6.4. (*****************) \!\(\* ButtonBox[\(2.6 .4\), ButtonStyle->"MainBookLink"]\) (*****************) -------------------------- I did some timing tests for the different ways of defining functions, and the results were very interesting. I used ($HistoryLength=0) so memory used wouldn't increase. I also did it with a new list each time so the kernel couldn't get the results out of the cache table. In[1]:= $HistoryLength=0; lst=Table[Random[],{4 10^4}]; In[2]:= Map[2#&,lst];//Timing Out[2]= {3.24 Second,Null} In[3]:= f[x_]:=2x lst=Table[Random[],{4 10^4}]; In[4]:= Map[f,lst];//Timing Out[4]= {5.71 Second,Null} In[5]:= lst=Table[Random[],{4 10^4}]; In[6]:= Map[Function[x,2x],lst];//Timing Out[6]= {6.31 Second,Null} However, the results above would vary slightly when repeated. This may be because I am using Windows 95. I once heard something about how the Win 95 OS makes it impossible for Timing to give an accurate result. If anyone has questions, just ask. Regards, Ted Ersek
- Follow-Ups:
- Re: RE: "f[x_]:= 2 x" vs. "f = 2 #&"
- From: Jurgen Tischer <jtischer@col2.telecom.com.co>
- Re: RE: "f[x_]:= 2 x" vs. "f = 2 #&"