Converting expressions into functions

I have defined an expression, such as

a = x


I would like to convert this into a function, such as

f[x_]:=x


However, in my case, the expression on the right-hand-side of a is rather complicated, so I do not want to manually write the expression on the right-hand-side of the function definition. I would like to write something like

f[x_]:=a


I know that this will not work. Is there a way to evaluate a in the function definition to ensure that I have actually defined a function in the end?

-
Instead of writing a = x and then trying to wrestle with it, why not simply write f[x_] := x or if you need to evaluate the rhs, f[x_] := Evaluate@foo? Further still, if you need to simultaneously assign it to a for whatever purpose, f[x_] := a = x? Is there some reason you're doing it in a roundabout way? –  rm -rf Nov 8 '12 at 21:07
Why not use f[x_] = a instead of f[x_] := a? –  Szabolcs Nov 8 '12 at 21:09
All the answers have been very helpful. Most of what has been said, I had read once before, but I was stumped because I was still getting unexpected behavior. It turns out that the problem I had was actually caused by a HoldForm that was buried inside the complicated expression on the right-hand-side of a, from where I misused one of my own functions. –  Carl Morris Nov 8 '12 at 22:12
add comment

1 Answer

In places where a function holds its arguments you can force evaluation by wrapping Evaluate. So for instance Hold[Evaluate[1+2]] will give you 3. The reson the right hand side is not evaluated is because SetDelayed has HoldAll:

 Attributes[SetDelayed]

{HoldAll, Protected, SequenceHold}


but you can simply force evaluation in the same manor:

 a = x^2
f[x_] := Evaluate[a]

f[k]

k^2


Depending on how much of your expression you want to evaluate this may work, but there may be cases where you need more control over the evaluation leaving some terms unevaluated until the actual function application of f. If this is the case and this doesn't work for you please extend your question.

As added by Szabolcs. Using Set rather then SetDelayed will also clear this up, since it doesn't hold its right hand side, only the left hand side (the first argument) arguments:

 Attributes[Set]

{HoldFirst, Protected, SequenceHold}


And here is a nice documentation reference again provided by Szabolcs: http://reference.wolfram.com/mathematica/tutorial/ImmediateAndDelayedDefinitions.html

-
Isn't this the same as f[x_] = a? –  Szabolcs Nov 8 '12 at 21:10
@Szabolcs Yes, I might have written this out, I really just wanted to explain the reason behind why it doesn't work out and how you in general get around this. I feel like getting to know the concept of Hold and how it works is something which can save a lot of early frustration with using Mathematica. –  jVincent Nov 8 '12 at 21:13
Including a link in your answer to this doc page would be valuable: reference.wolfram.com/mathematica/tutorial/… –  Szabolcs Nov 8 '12 at 21:17
add comment