Re: Evaluation of args in pure functions
- To: mathgroup at smc.vnet.net
- Subject: [mg17066] Re: [mg16924] Evaluation of args in pure functions
- From: "Wolf, Hartmut" <hwolf at debis.com>
- Date: Wed, 14 Apr 1999 02:12:09 -0400
- Organization: debis Systemhaus
- References: <199904080632.CAA24227@smc.vnet.net.>
- Sender: owner-wri-mathgroup at wolfram.com
Ciao Andrea, stimulated by your posting (and the replies to it) I did some testing about the steps of evaluation in different circumstances -- although we have that scanty description in A.4.1 and A.4.4 for times when we are not in the mood to scrutinize 2.3, 2.4 once more. Since this test is funny (and somewhat enlighting, I suppose) I'd like to publish it to the group: We try to observe the evaluation sequences in different cases through added Print statements. In[1]:= u[x_]:=(Print["hopp"];x) In[2]:= v[x_]:=(Print["hipp"];x) In[3]:= u[v[1]] "hipp" "hopp" Out[3]= 1 Ok, v ist evaluated first, then u does it's job at (the result of) v[1] In[4]:= u[Unevaluated[v[2]]] "hopp" "hipp" Out[4]= 2 First u is called with the (unevaluated) argument v[1], that result is then evaluated The operator expr1 @ expr2 essentially is syntactical sugar for expr1[expr2 ] (except for grouping -> A.2.7) In[5]:= u at v[3] "hipp" "hopp" Out[5]= 3 In[6]:= u at Unevaluated[v[4]] "hopp" "hipp" Out[6]= 4 So there is no difference. Coming closer to your question, and testing with pure function: In[14]:= u[#]& @v[9] "hipp" "hopp" Out[14]= 9 Nothing peculiar, at first the Head of the expression ist evaluated, i.e. Function (which we didn't make talking) generates a functional object (for which we do not have a notation -- it's ephemeral, we can't see it in the input, we can't see it in the output) without evaluating its argument (i.e. u[#]). It's only now that we have something that can be made working, so now v evaluates, then that functional object moves the argument (evaluated v[9]) into u, which then executes. In[16]:= u[#]& @Unevaluated[v[10]] "hipp" "hopp" Out[16]= 10 This is to be contrasted with case 2 above and comes out different! But we can understand that now: v[10] is passed unevaluated to the functional object (which moves it into u), but then v is evaluated there, before finally u fires. In[17]:= u[Unevaluated[#]]& @Unevaluated[v[11]] "hopp" "hipp" Out[17]= 11 In[18]:= u[Unevaluated[#]]& @v[12] "hipp" "hopp" Out[18]= 12 So the cases 11 and 12 support our theory for 10. Case 11 holds v further unevaluated after it is moved into u, executing u first, then v. Case 12 is ineffective since v is evaluated before it gets moved into u. To get more evidence, you may try to make Function talking: In[20]:= SetAttributes[talkingFunction, HoldAll] In[21]:= TalkingFunction[body_]:=(Print["makefun"];Function[(Print["move"];body)]) and do the tests: In[22]:= talkingFunction[u[#]][v[1009]] In[23]:= talkingFunction[u[#]][Unevaluated[v[1010]]] In[24]:= talkingFunction[u[Unevaluated[#]]][Unevaluated[v[1011]]] In[25]:= talkingFunction[u[Unevaluated[#]]][v[1012]] So we have to recognize that f[x] and Function[f[#]][x] indeed is not the same! The expression f[x] is decoded by pattern matching, and the "arguments" are moved into the body of its definition through named patterns, resulting in a transformed expression, which then is treated further. Wheras for Function[f[#]][x] the arguments are identified and moved into the body by position in the calling sequence, and this is an _additional_ intermediate step in the calculation process, where further evaluation of arguments can take place (cases 10, 1010). So we need Unevaluate twice (cases 11, 1011) to match the case 2. Finally we can seperate the preparation of the functional object and its execution into two seperate execution cycles: In[26]:= foo=talkingFunction[u[#]] In[27]:= foo[v[2009]] In[28]:= foo[Unevaluated[v[2010]]] and In[29]:= foouu=talkingFunction[u[Unevaluated[#]]] In[30]:= foouu[Unevaluated[v[2011]]] In[31]:= foouu[v[2012]] (If you want to have my full notebook, just request it by mailto:hwolf at debis.com ) Kind regards Hartmut Wolf
- References:
- Evaluation of args in pure functions
- From: Andrea Sosso <sosso@dns.ien.it>
- Evaluation of args in pure functions