I need to create a function programmatically. For example, suppose I’ve got:
- mon – a Symbol
- mons – a List of Symbols
- vars – another List of Symbols (same Length)
and want to make a function as:
Function[{«mon»}, Function[«mons», Internal`InheritedBlock[«vars», «vars[[1]]» =.; «vars[[2]]» =.; ... «vars[[-1]]» =.; «vars[[1]]» = «mons[[1]]»; «vars[[2]]»[t] = «mons[[2]]»; ... «vars[[-1]]»[t] = «mons[[-1]]»; «mon» ]]]
where «» denotes injecting from the given mon, mons, and vars.
So the input
mon = Unique[NDSolve`Monitor]; mons = Table[Unique[mon], {3}]; vars = {t, x, y};
would result in the desired output:
Function[{NDSolve`Monitor$ 3080}, Function[{NDSolve`Monitor$ 3080$ 3081, NDSolve`Monitor$ 3080$ 3082, NDSolve`Monitor$ 3080$ 3083}, Internal`InheritedBlock[{t, x, y}, t =.; x =.; y =.; t = NDSolve`Monitor$ 3080$ 3081; x[t] = NDSolve`Monitor$ 3080$ 3082; y[t] = NDSolve`Monitor$ 3080$ 3083; NDSolve`Monitor$ 3080 ]]]
One possible solution involves building up a String
, then using ToExpression
:
str = "Function[{" <> ToString[mon] <> "}, Function[" <> ToString[mons] <> ", Internal`InheritedBlock[" <> ToString[vars] <> ", "; Do[ str = str <> ToString[var] <> "=.;\n" , {var, vars}]; str = str <> "t=" <> ToString[mons[[1]]] <> ";\n"; Do[ str = str <> ToString[vars[[i]]] <> "[t]=" <> ToString[mons[[i]]] <> ";\n" , {i, 2, Length[vars]}]; str = str <> ToString[mon] <> "]]]\n";
but this is kind of inelegant and can be slow for large lists.
Are there any nicer and/or faster alternatives?