How to "soft-code" a Block?

*To*: mathgroup at smc.vnet.net*Subject*: [mg113302] How to "soft-code" a Block?*From*: dr DanW <dmaxwarren at gmail.com>*Date*: Sat, 23 Oct 2010 07:03:48 -0400 (EDT)

Hard coding a Block is easy: In[1]:= Block[{a = b, b = c, c = 3}, {a, b, c} ] Out[1]= {3, 3, 3} But what if my variable list and expression are themselves values, as in: In[1]:= vals = {a = b, c = 3, b = c}; expr = {a, b, c}; Block[vals, expr] During evaluation of In[1]:= Block::lvlist: Local variable specification vals is not a List. >> Out[3]= Block[vals, expr] Which fails for many obvious reasons. However, is there a way to do this, as in: In[1]:= vals = {a -> b, c -> 3, b -> c}; expr = {a, b, c}; RuleBlock[vals, expr] Out[3]= {3, 3, 3} How can I write RuleBlock[], which functions as a scoping construct and Set's the left hand sides to the right hand sides of all the Rules in the list? Why do I need this? I am writing a modeling program which builds up a complicated compound expression in terms of some parameters. The expression can be evaluated quickly once numerical values of the parameters are supplied. I also want to be able to evaluate the expression for different sets of parameters. The obvious solution, using expr //. vals, does not always work for several reasons: * The expression contains several SparseArray's, and Replace does not work within SparseArray's. * The expression may contain other scoping structures or functions which do not respond to Replace unless wrapped with Evaluate every place it is used * This is a complicated, programmatically generated expression, and finding every instance where Replace would have to be Evaluate'd would be tedious (meaning: error prone) This would be so much easier with a scoping structure I could soft- code. I have attempted this with: RuleBlock[r_?OptionQ, exp_] := Block[ Evaluate[r[[All, 1]]], Evaluate[r /. Rule -> Set]; exp ]]; Which seems to work most of the time, but has failed me for reasons that I cannot explain on some occasions. I can't come up with a simple example that demonstrates this failure. Whenever I work this hard on something this low-level in Mathematica, it usually means that there is an obvious solution I missed, or a feature in Mathematica I am unaware of. I have struggled with this one for many years and have used various band-aids, but I am tired of it and want to have a robust solution that works all the time. Any suggestions? Regards, Daniel