7
votes

When I use Manipulate I can do:

Manipulate[x, {u, 1, 10}]

In reality my controls are many and complicated, so I would prefer to take their definition out of the Manipulate expression, like that:

control = {u, 1, 10}
Manipulate[x, control]

But that does result in a an error:

Manipulate argument control does not have the correct form for a \
variable specification.

Why doesn't it work that way?

2
The example you provided, and what I see in most answers is that the complexity of the code is not reduced at all. Some of the answers create a very complex piece of code using significantly more characters, a bunch of extra scoping constructs etc. I feel that just improving the layout of your code (each control on it's own line, visually grouping related controls etc.) in most cases suffices. - Sjoerd C. de Vries
Through the answers I understand better what's going on, but you are exactly right: None of the constructs makes the code really simpler. What drives me crazy is the insane nesting depth of brackets in my code. Probably that's the Lisp way of doing it, but isn't there a way to make my programs more linear? - Ludwig Weinzierl
@Sjoerd well, if a piece of code appears in one place, then I mostly agree with you. Doing this usually makes sense if either a) you are using the code in more than one place, or b) the complete code is getting too long to easily modify. For instance, I have a notebook with a Manipulate the code for which does not on my macbook's 13 inch screen. I have to either use a trick like this, or try to load the whole thing in my head every time I need to modify it. As I already have to think hard about the problem I am actually solving, I'd rather reduce code complexity by adding a few characters. - acl
@Sjoerd is right, the layout can help. The Mma notebook does an ok job of indenting lines if you but explicit carriage returns in. Although acl and I answered your original question, I think that the better way to simplify a big manipulate is to leave the controls in there but to move everything else out. See e.g. some of S M Blinder's demonstrations - eg Newton's Cradle. - Simon

2 Answers

11
votes

Manipulate has the HoldAll attribute. You can force control to evaluate and everything works ok

control = {u, 1, 10};
Manipulate[x[u], Evaluate[control]]

The problem with this is that the variable u is not properly localised, so if you have already set, e.g., u=1 somewhere, then the Manipulate will return an error.

It might be better if you use appropriate scoping constructs such as With or DynamicModule depending on exactly what you're trying to do.

This is maybe overkill, but it ensures that u is local and moves control outside of the manipulate:

DynamicModule[{u}, With[{control = {u, 1, 10}}, Manipulate[x[u], control]]]
10
votes

This

con = {u, 1, 10};
Manipulate[
 u,
 Evaluate@con
 ]

does work. I suppose it doesn't work without the Evaluate because

Attributes[Manipulate]

shows that Manipulate has the attribute HoldAll (but I may be wrong). To see the effect of this attribute, try this:

SetAttributes[f, HoldAll]
f[con]
f[Evaluate@con]
g[con]
(*
f[con]
f[{u, 1, 10}]
g[{u, 1, 10}]
*)

Thus, it appears that due to the HoldAll atribute, Manipulate simply does not see "inside" con unless you explicitly evaluate it.