Re: Variables within With statement
- To: mathgroup at smc.vnet.net
- Subject: [mg123690] Re: Variables within With statement
- From: Leonid Shifrin <lshifr at gmail.com>
- Date: Fri, 16 Dec 2011 05:40:58 -0500 (EST)
- Delivered-to: l-mathgroup@mail-archive0.wolfram.com
- References: <201112150951.EAA22803@smc.vnet.net>
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 On Thu, Dec 15, 2011 at 12:51 PM, Harvey P. Dale <hpd1 at nyu.edu> wrote: > Is there any easy way to have one variable within a With > statement take its value from a prior variable in the same With > statement? For example, if I evaluate With[{a = 5, b = 10 a}, a + b], I > get 5 + 10a, and what I want is 55. I can get there like this: With[{a > = 5}, With[{b = 10 a}, a + b]] -- which does produce 55 -- but it would > be nicer if I could use a single With statement and get b, within it, to > take its value from a. > > Thanks. > > Harvey > >
- References:
- Variables within With statement
- From: "Harvey P. Dale" <hpd1@nyu.edu>
- Variables within With statement