MathGroup Archive 2011

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

Search the Archive

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
>
>


  • Prev by Date: Re: Problem with integration
  • Next by Date: Re: incrementing elements of a SparseArray
  • Previous by thread: Re: Variables within With statement
  • Next by thread: Re: Variables within With statement