MathGroup Archive 2010

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: How to "soft-code" a Block?

On 23.10.2010 13:03, dr DanW 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
Hi Daniel,
look at the following code:

CreateBlock[lvals_, rvals_, expr_] := Module[{v, myBlock},
   v = Thread[mySet[lvals, rvals]];
   SetAttributes[myBlock, HoldAll];
       ] /. vals -> v /. mySet -> Set /. myBlock -> Block
CreateBlock[{a, b, c}, {b, c, 3}, {a, b, c}] /. myBlock -> Block

We first create a Block that can not evaluate by giving it an arbitrary 
Head "myBlock" and the attribute HoldAll. We must further prevent Set 
from evaluating by using an arbitrary name "mySet". With this 
preparation we can set up "myBlock". Having done so, we change "mySet" 
to "Set" and "myBlock" to "Block".

By the way, why are you using Block and not Module? Do you really want 
to use dynamic scoping?

cheers Daniel Huber

  • Prev by Date: Re: Graphics: How to get values corresponding to
  • Next by Date: Re: issue with LinearSolve[] when using SparseArray when
  • Previous by thread: Re: Writing functions in packages that define values of global variables
  • Next by thread: Re: issue with LinearSolve[] when using SparseArray when