6
$\begingroup$

One can do

expression = a + 1;

f[a_] := Evaluate[expression]

but how would one do something like this

expression = a + 1;

g[x_] := Module[{a,b},
  a=1;
  b=Evaluate[expression];
  x*b
 ]

so that only variable b right-hand side would be evaluated and not the whole Module. This would be useful for using long formulas generated by mathematica in own function definitions.

The solution suitable for me:

Thanks Jens for the answer, that pointed me to the right direction. The solution I was looking for and works for me is

expression = a + 1;

With[{expr=expression},
 f[x_]:=Block[{a,b},
   a = 1;
   b = expr;
   x*b
 ]
]

So using With outside of SetDelayed causes evaluation of expression as desired (Jens answer) and the naming problem (a and $a) is solved by using Block instead of Module.

$\endgroup$
2
  • $\begingroup$ Welcome to Mathematica.SE! I hope you will become a regular contributor. To get started, 1) take the introductory Tour now, 2) when you see good questions and answers, vote them up by clicking the gray triangles, because the credibility of the system is based on the reputation gained by users sharing their knowledge, 3) remember to accept the answer, if any, that solves your problem, by clicking the checkmark sign, and 4) give help too, by answering questions in your areas of expertise. $\endgroup$
    – bbgodfrey
    Aug 10, 2015 at 22:01
  • $\begingroup$ Relevant link, though not necessarily a duplicate due to Module: Evaluation in lambda function. There may well be other duplicate Q&As, but I haven't found one yet. $\endgroup$
    – Jens
    Aug 10, 2015 at 23:06

2 Answers 2

8
$\begingroup$

There are two possibilities you could be aiming for. First, I'll take your question literally and just inject expression into the Module:

expression = a + 1;
With[{expression = expression},
 g[x_] := Module[
   {a, b},
   a = 1;
   b = expression;
   x*b]]

expression = 1

(* ==> 1 *)

g[xi]

(* ==> (1 + a) xi *)

As the result after changing expression shows, the earlier value of expression has been used in the definition of the Module. This was achieved by using With just as a wrapper that introduces the current value of expression literally in the definition of g.

However, this probably doesn't do what you expected, because the symbol a still appears in the last result. You probably wanted a to be replaced by 1. This could for example be done as follows:

expression = a + 1;
With[{expression = expression /. a -> 1},
 h[x_] := Module[
   {b},
   b = expression;
   x*b]]

expression = 1

(* ==> 1 *)

h[xi]

(* ==> 2 xi *)

The reason that the definition a=1; for a local variable a inside the Module doesn't work is that Mathematica doesn't actually have local variables in the strict sense. Inside the Module, it renames a to something else (a$), but the injected expression was outside of the scope where this renaming happened. Therefore, a in expression isn't the same variable as a inside the Module. To avoid this mismatch, I do the replacement of a by 1 outside of the Module.

$\endgroup$
1
$\begingroup$

You can use Inactivate and Activate to control the evaluation of the right-hand side.

expression = Inactivate[a + 1];

g[x_] :=
  x Activate[expression /. a -> 1];

g[2]
(* 4 *)

expression
(* a + 1 *)

Inactivate prevents the execution while Activate executes without losing the inactivated expression.

Hope this helps.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.