# Manipulate and function definition

I have read the documentation, and know the way Initialization works with Manipulate, but I can't seem to understand why this piece of code

Manipulate[
Plot[h[x], {x, -3, 3}]
, {b, -5, 5}
, Initialization :> (h[x_] := x + b)]


produces a static graph. I know that if I change the function h[x] to h[x_,b_], then the Manipulate gives a dynamic graph, but I would like the function h to have one parameter (instead of two), if possible.

What am I missing here? Thanks, as always, for all help!

• Try h[x]/.b->b – Kuba Sep 14 '13 at 15:04
• Since you don't say, I can't comment on your reasons for really wanting h to have only one parameter. But if it were my code, I find it difficult to imagine that I'd be happy with any variant of the one-parameter solution. – John Fultz Sep 14 '13 at 16:56
• Because b is not explicitly present in the body of Manipulate it is not being tracked. You need to add TrackedSymbols :> {b} to the Manipulate options. – Simon Woods Sep 14 '13 at 18:21
• @JohnFultz: I don't quite understand your comment: would you be happy with the one-parameter function h? Can you elaborate why yes/no? Thanks! – Gabriel Sep 14 '13 at 23:49
• @Gabriel I'm thinking of Manipulate as a form of DynamicModule. DynamicModule does lexical scoping. It's generally a bad idea to assign a lexically scoped localized variable to a global symbol (as you are assigning h in terms of b). It's difficult to understand, it may not do what you want, and the behavior might change depending upon implementational details. Therefore, I would strongly prefer DynamicModule (and Module) variables to be passed directly as function arguments without side-effect assignments. – John Fultz Sep 15 '13 at 13:56

I'm posting this to get the answer in Simon Woods' comment on record.

Manipulate[Plot[h[x], {x, -3, 3}],
{b, -5, 5},
TrackedSymbols -> {b},
Initialization :> (h[x_] := x + b)]


I think this is the simplest solution to the problem as posed.

The variable b is local inside the Manipulate. The Initialization construct acts just as if the initialization code was executed before the Manipulate -- hence is outside its scope. So it only looks like the b is inside the scope of the Manipulate.

If you really want to define h inside the Manipulate to have a single argument, you can accomplish it this way:

bOld = 100;
Manipulate[ If[bOld != b, h[x_] := x + b; bOld = b;];
Plot[h[x], {x, -3, 3}], {b, -5, 5}]


The bOld and If are used to make sure the function does not continuously retrigger the evaluation and only redefines h[x] when needed (i.e., when b changes).