0
$\begingroup$

How do I specify an arbitrary number of variable names and initialize them inside of a Module or Block?

For example, I want to do something like:

Module[Join[{mu = 100}, Array[(Symbol["lambda"<> ToString@#] = 0) &, 10]],
      lambda3 = 7; Print[mu <> lambda2]; Print[mu <> lambda3];
     ]

Instead, I get all sorts of errors about improper local variable definitions. I tried wrapping things in Evaluate, or making my own Hold and then Release sequence, but nothing I did seemed to work.

Any help would be much appreciated!

Best wishes, Andy

$\endgroup$
8
  • $\begingroup$ @Kuba while I understand that this may seem like a similar problem, I think mine is slightly different. If I take the solution given there and create my own listModule or listBlock function, then in order to write "params = vals" like they do in that example I have to scope my variables OUTSIDE of the Module or Block. This defeats the purpose of using Module in the first place. $\endgroup$
    – afurn
    Aug 21, 2013 at 17:16
  • $\begingroup$ afurn, specifically what input syntax do you want to use? Your pseudocode is not clear to me. $\endgroup$
    – Mr.Wizard
    Aug 21, 2013 at 17:19
  • $\begingroup$ @MichaelE2 We're thinking the same thing. $\endgroup$
    – Mr.Wizard
    Aug 21, 2013 at 17:23
  • $\begingroup$ @Mr.Wizard I believe I have now changed the question to specify that I can use Symbol[] to generate the symbols. I know that the bracket notation for variable names is not often accepted as a symbol (e.g. for integration). $\endgroup$
    – afurn
    Aug 21, 2013 at 17:24
  • $\begingroup$ Maybe I was too hasty, but I'm not sure $\endgroup$
    – Kuba
    Aug 21, 2013 at 17:25

1 Answer 1

3
$\begingroup$

It's difficult to understand exactly what you want, but by one interpretation you don't need any special initialization at all as you are using indexed variables which would normally be the first recommendation for such questions. Perhaps the missing piece of the puzzle is a default value which can be defined with e.g. l[_] = 0.

Module[{mu = 100, l},
  l[_] = 0;
  l[3] = 7;
  Print[mu, l[2]];
  Print[mu, l[3]];
]

1000

1007

A second interpretation is that this is a duplicate of: How to set Block local variables by code?

You could create your symbol names as strings, then use the code there, e.g.:

Join @@ MakeExpression @ Array["lambda" <> ToString@# &, 5] /.
  _[vars__] :> Block[{vars}, body]

Or, if you wish to make assignments at the same time this is similar to my answer to Constructing symbol definitions for With which includes proper scoping. Adapting that answer for Module:

SetAttributes[listModule, HoldAll];

listModule[(set : Set | SetDelayed)[L_, R_], body_] :=
  set @@@ Thread[Hold @@@ {L, R}, Hold] /. _[x__] :> With[{x}, body]

Now:

vars = Join @@ MakeExpression @ Array["lambda" <> ToString@# &, 5]
vals = Array[Prime, 5]
listModule[vars = vals, lambda2 + lambda5]
HoldComplete[lambda1, lambda2, lambda3, lambda4, lambda5]

{2, 3, 5, 7, 11}

14

Of course the Array / MakeExpression code could be included in your function if your input is standardized.

$\endgroup$
2
  • $\begingroup$ I believe that your first solution and interpretation is what I have been looking for. I'm going to try it in my code now and will let you know how it goes. Thank you! $\endgroup$
    – afurn
    Aug 21, 2013 at 17:41
  • $\begingroup$ @afurn You're welcome. If it doesn't work I'm confident that we can get something that does as long as you clearly specify your desired input. $\endgroup$
    – Mr.Wizard
    Aug 21, 2013 at 17:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.