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