Using Hold, ReleaseHold, and Unevaluated

*To*: mathgroup at smc.vnet.net*Subject*: [mg2316] Using Hold, ReleaseHold, and Unevaluated*From*: claudio at wizard.hip.berkeley.edu (Claudio Fahey)*Date*: Mon, 23 Oct 1995 12:45:04 -0400*Organization*: U. C. Berkeley

I'm trying to write a function that constructs a pure function. I would like to do the following (for example): In[1] := f = Func[{{x1,y1},{x2,y2}}, (x1-x2)^2 + (y1-y2)^2]; In[2] := f[{{a,b}, {c,d}}] Out[2] = (a-c)^2 + (b-d)^2 The function I want to write, Func, is similar to Function but it accepts nested lists of variables as well as a flat list. Of course, I could have created a simple definition for f such as In[1] := f[{{x1_,y1_},{x2_,y2_}}] := (x1-x2)^2 + (y1-y2)^2; but I want to create a pure function so that I may define this function within another function. Here's my attempt at Func: Func[varpattern_, f_] := Module[ Evaluate[Flatten[varpattern]], (varpattern = #; f) & ]; I need to evaluate the first parameter because Module has the HoldAll attribute. I need to flatten varpattern because Module needs a flat list of variables and varpattern may be a nested list of variables. This function works fine but I would like it to have the HoldAll attribute. Without this attribute, the following problem occurs: In[1] := x1 = 1.0; In[2] := f = Func[{{x1,y1},{x2,y2}}, (x1-x2)^2 + (y1-y2)^2] Out[2] = Module::lvsym: Local variable specification {2, y1, x2, y2} contains 2 which is not a symbol or an assignment to a symbol. Module[{2, y1, x2, y2}, 2 2 ({{2, y1}, {x2, y2}} = #1; (2 - x2) + (y1 - y2) ) & ] The x1 in the parameter list was replaced with 1.0. The HoldAll attribute would prevent the x1 in the parameter list from being evaluated. However, even with the HoldAll attribute, x1 is still being evaluated because Evaluate is being called to flatten the nested list of variables. I've tried various combinations of mapping Hold, Unevaluated, and ReleaseHold but I've been unable to make Func work properly (like Function but with nested variable lists). I basically want to ONLY perform the flatten operation. I want the variable names (and the function f) to remain unevaluated. Does anybody know how to do this? Claudio Fahey