7

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?

Ludwig Weinzierl
  • 15,980
  • 10
  • 45
  • 49
  • 1
    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 Aug 21 '11 at 15:08
  • 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 Aug 21 '11 at 15:28
  • 1
    @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 Aug 21 '11 at 15:49
  • @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](http://stackoverflow.com/users/559318/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](http://demonstrations.wolfram.com/author.html?author=S.+M.+Blinder) - eg [Newton's Cradle](http://demonstrations.wolfram.com/PhenomenologicalApproximationToNewtonsCradle/). – Simon Aug 21 '11 at 22:32

2 Answers2

11

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]]]
Simon
  • 14,631
  • 4
  • 41
  • 101
10

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.

acl
  • 6,490
  • 1
  • 27
  • 33
  • 1
    You beat me by *that* much! So, +1 – Simon Aug 21 '11 at 14:42
  • @Simon thanks! +1 for you too. Guess I'll end up with less upvotes anyway :) – acl Aug 21 '11 at 14:45
  • Thanks, that works when I copy and paste your example into a new worksheet. In my old worksheet I had to press Shift+Enter on every line before it worked, even on the line with control = {u, 1, 10}, which hadn't changed. Why do I have to reevaluate the lines? – Ludwig Weinzierl Aug 21 '11 at 14:48
  • @Ludwig I don't know. It sounds like some issue with end-of-line characters, but who knows... Did they end up in separate cells? (you can tell by the cell brackets on the right edge of your mma window) – acl Aug 21 '11 at 14:51
  • @acl: I can't reproduce the error, it works as expected now, thanks. – Ludwig Weinzierl Aug 21 '11 at 14:57