# How to generate abstraction clauses programmatically?

I would like to call some complex plotting function, which accepts a list of variables and would like to get sliders for each variable.

Currently I write something like below

PlotSines[a_List] := Block[{funcs},
funcs = Table[Sin[a[[i]] x] + i - 1, {i, 1, Length[a]}];
Plot[funcs, {x, -5, 5}]
];

Manipulate[PlotSines[{a1, a2, a3}], {{a1, 1}, 0.1, 5}, {{a2, 1}, 0.1, 5}, {{a3, 1}, 0.1, 5}] i.e. explicitly writing each "abstraction" clause of kind {{a1, 1}, 0.1, 5}. I name them "abstraction" clauses like in lambda calculus, because these clauses "remove" mentioned variable from outer expression.

Now I want to have variable number of a-s and so I can't hardcode expression then.

Can I generate such construction programmatically, so that it generated list of some names, acceptable by Manipulate function?

I tried to write this way

varlist = Table[Symbol[ToString[StringForm["a", i]]], {i, 1, 5}]


which gave

{a1, a2, a3, a4, a5}


then

clauses = Sequence[Table[{{a, 1}, 0.1, 5}, {a, varlist}]]


which gave

Sequence[{{{a1, 1}, 0.1, 5}, {{a2, 1}, 0.1, 5}, {{a3, 1}, 0.1, 5}, {{a4, 1}, 0.1, 5}, {{a5, 1}, 0.1, 5}}]


I was hoping sequnce will "expand" inside manipulate and wrote

Manipulate[PlotSines[varlist], clauses]


but it complained

Manipulate::vsform: Manipulate argument clauses does not have the correct form for a variable specification.


UPDATE

I thought I should play with evaluation order somehow. I tried to write

 Manipulate[PlotSines[varlist], Evaluate[clauses]]


but it drew apparently PlotSines function was executed before Manipulate called it

• – Kuba
Oct 19 '17 at 14:08

PlotSines[a_List] :=
Block[{funcs},
funcs = Table[Sin[a[[i]] x] + i - 1, {i, 1, Length[a]}];
Plot[funcs, {x, -5, 5}]];

foo[n_Integer] := Module[{vars, varSpec},
vars = Table[Unique["x"], {n}];
varSpec = Table[{{vars[[i]], 1, StringTemplate["a"]@i}, 0.1, 5}, {i,
Length@vars}];

Manipulate[
PlotSines[vars],
Evaluate[Sequence @@ varSpec]
] /. OwnValues[vars]
]


I am creating unique xi because I don't want to care if they already exist. Then I just label them as consecutive ai :)

varlist = Table[Symbol["a"<>ToString[i]],{i,1,5}];
clauses = Table[{{a,1},0.1,5},{a,varlist}];
manipulate = "Manipulate[PlotSines["<>ToString[varlist]<>"],
Evaluate[Sequence@@"<>ToString[clauses]<>"]]";
ToExpression[manipulate]


Apparently Manipulate will automatically hold all of its elements in unevaluated form, but that makes this specific problem a bit tricky to solve. The easiest method I've seen to deal with the holds is to write the command in full as a string and then execute it.

• This will fail if e,g, a1 = 2; was evaluated or any of ai have value
– Kuba
Oct 19 '17 at 15:59

I found a way without string coding:

PlotSines[a_List] := Block[{funcs},
funcs = Table[Sin[a[[i]] x] + i - 1, {i, 1, Length[a]}];
Plot[funcs, {x, -5, 5}]
];

n = 5
varlist = Table[Symbol[ToString[StringForm["a", i]]], {i, 1, n}]
clauses = Sequence @@ Table[{{a, 1}, 0.1, 5}, {a, varlist}]
Activate[Inactive[Manipulate][Inactive[PlotSines][varlist], clauses]]


draws • This will fail if e,g, a1 = 2; was evaluate or any of ai have value.
– Kuba
Oct 19 '17 at 15:14