Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using `With` with a list of `Rules` - but without affecting the normal behaviour of `With`

Say I have a list of Rules

rules = {a -> b, c -> d};

which I use throughout a notebook. Then, at one point, it makes sense to want the rules to apply before any other evaluations take place in an expression. Normally if you want something like this you would use

In[2]:= With[{a=b,c=d}, expr[a,b,c,d]]
Out[2]= expr[b, b, d, d]

How can I take rules and insert it into the first argument of With?


Edit

BothSome solutions fail do all that I was looking for - but I should have emphasised this point a little more. See the bold part above.

For example, let's look at

rules = {a -> {1, 2}, c -> 1};

If I use these vaules in With, I get

In[10]:= With[{a={1,2},c=1}, Head/@{a,c}]
Out[10]= {List,Integer}

Some versions of WithRules yield

In[11]:= WithRules[rules, Head/@{a,c}]
Out[11]= {Symbol, Symbol}

(Actually, I didn't notice that Andrew's answer had the Attribute HoldRest - so it works just like I wanted.)

like image 846
Simon Avatar asked Mar 04 '11 02:03

Simon


1 Answers

You want to use Hold to build up your With statement. Here is one way; there may be a simpler:

In[1]:= SetAttributes[WithRules, HoldRest]

In[2]:= WithRules[rules_, expr_] := 
 With @@ Append[Apply[Set, Hold@rules, {2}], Unevaluated[expr]]

Test it out:

In[3]:= f[args___] := Print[{args}]

In[4]:= rules = {a -> b, c -> d};

In[5]:= WithRules[rules, f[a, c]]

During evaluation of In[5]:= {b,d}

(I used Print so that any bug involving me accidentally evaluating expr too early would be made obvious.)

like image 70
Andrew Moylan Avatar answered Sep 21 '22 10:09

Andrew Moylan