Re: How to "soft-code" a Block?
- To: mathgroup at smc.vnet.net
- Subject: [mg113354] Re: How to "soft-code" a Block?
- From: Leonid Shifrin <lshifr at gmail.com>
- Date: Mon, 25 Oct 2010 06:39:47 -0400 (EDT)
Hi Daniel, Your first attempt can be modified to work: Unevaluated[Block[vals,expr]]/.OwnValues[vals] gives a result equivalent to the hard-coded block. Your suggestion with rules looks too complex to me in this context (I used a similar construct but in very different situations). The way to make a really simple run-time Block would be to wrap your declaration list in Hold: heldvals = Hold[{a=b,c=3,b=c}]; Now, the following simple function will work: ClearAll[runtimeBlock]; SetAttributes[runtimeBlock,HoldRest]; runtimeBlock[Hold[vars_List],body]:=Block[vars,body]; You use it as runtimeBlock[heldvals,{a,b,c}] or expr = {a,b,c} runtimeBlock[heldvals,expr] Alternatively, the following will also work: Block@@Append[heldvals,Unevaluated[expr]] While I checked the results on a different PC, I typed this manually here, so there could be some typos. Hope this helps. Regards, Leonid On Sat, Oct 23, 2010 at 7:03 AM, dr DanW <dmaxwarren at gmail.com> wrote: > 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 > > >