This question has been asked before. The real problem is to integrate such
a use case nicely with existing uses for With. In particular, we may want
it to work correctly with the shared local variables, and as a r.h.s. of
the assignment operator. There were a few threads devoted to it both
here and on StackOverflow. Here is my implementation of the scoping
construct which does that:
ClearAll[LetL];
SetAttributes[LetL, HoldAll];
LetL /: Verbatim[SetDelayed][lhs_, rhs : HoldPattern[LetL[{__}, _]]] :=
Block[{With}, Attributes[With] = {HoldAll};
lhs := Evaluate[rhs]];
LetL[{}, expr_] := expr;
LetL[{head_}, expr_] := With[{head}, expr];
LetL[{head_, tail__}, expr_] :=
Block[{With}, Attributes[With] = {HoldAll};
With[{head}, Evaluate[LetL[{tail}, expr]]]];
What this does it to generate the nested With statements at run-time, and
then execute them. For example:
In[63]:= a=1;b=2;
LetL[{a=3,b=a+4},{a,b}]
Out[64]= {3,7}
You can see it better by using Trace:
In[66]:= Trace[LetL[{a=3,b=a+4},{a,b}],_With]
Out[66]=
{{{{With[{b=a+4},{a,b}]},With[{a=3},With[{b=a+4},{a,b}]]},With[{a=3},With[{b=a+4},{a,b}]]},With[{a=3},With[{b=a+4},{a,b}]],With[{b$=3+4},{3,b$}]}
Care was taken to avoid variable captures from the top-level (e.g. global
values for a and b above were ignored, as they should have been).
It is disccused more fully here:
http://stackoverflow.com/questions/5866016/question-on-condition/5869885#5869885
And the original discussion is in this thread:
http://groups.google.com/group/comp.soft-sys.math.mathematica/browse_thread/thread/3a5ae92bda1c7511
A similar discussion can be found here:
https://groups.google.com/group/comp.soft-sys.math.mathematica/browse_thread/thread/6fa6b0ad9d5d111c
with it's continuation here:
http://stackoverflow.com/questions/4198961/what-is-in-your-mathematica-tool-bag/5692010#5692010
Whether or not any of the suggested solutions can be called easy is a
matter of opinion. I used my version in many places and had no problems
with it.
Another approach that you may take is if you *insist* to use literal *With*
but change its properties. You can use code-generation techniques similar
to the one exposed here:
http://stackoverflow.com/questions/8373526/error-generating-localized-variables-as-constants/8377522#8377522
to achieve that. Actually, my version above also does that, but it
generates nested `With` statements at run-time.
Hope this helps.
Regards,
Leonid