Mathematica Stack Exchange is a question and answer site for users of Mathematica. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top
G[x_] := With[{a = 0}, With[{b = x}, a]]
G @ 0
F[x_] := With[{a = 0}, {b = x}, a]
F @ 0

gives

0
a

I would expect both to behave exactly the same.


It seems that referring to the parameter x invalidates any amount of previously defined variables, but none that come after:

F[x_] := With[{a = 0}, {s = 0}, {b = x}, {t = 0}, {w = 0}, {a, s, b, t, w}]
F @ 0

{a, s, 0, 0, 0}

Manually nested With or LetL don't have this problem:

F[x_] := LetL[{a = 0, s = 0, b = x, t = 0, w = 0}, {a, s, b, t, w}]
F @ 0

{0, 0, 0, 0, 0}

Referring to an earlier variable is also no problem

F[x_] := With[{a = 0}, {s = 0}, {b = a}, {t = 0}, {w = 0}, {a, s, b, t, w}]
F @ 0

{0, 0, 0, 0, 0}

Referring to Module variables gives the same problem:

H[] := 
  Module[{x = 0}, 
    With[{a = 0}, {s = 0}, {b = x}, {t = 0}, {w = 0}, {a, s, b, t, w}]]
H[]

This must be a bug in this undocumented feature. Maybe it has to do with the renaming that takes place.

share|improve this question
1  
I'm confused after reading this question and the answer too. With[] is documented to be always called with two arguments. Or not? – Gustavo Delfino 9 hours ago
2  
@GustavoDelfino yes, as OP said "bug in this undocumented feature". So it is not major concern before it is released but worth to be aware of. More about this functionality in: 121173 – Kuba 8 hours ago

A long comment:

Automatic renaming again:

ClearAll[F]; 
F[x_] := Hold[With[{a = x}, {b = x}, a]]; 
F[0] 
Hold[With[{a$ = 0}, {b = 0}, a]]

but in a quite strange manner...

It is strange, because I was expecting it already in DownValues, but this is not the case.

DownValues @ F
{HoldPattern[F[x_]] :> Hold[With[{a = x}, {b = x}, a]]}

So who does it? :) Here is a pure guess, if evaluation is really a replacement then I would blame RuleDelayed:

Hold[F[0]] /. Echo @ DownValues[F]
{HoldPattern[F[x_]]:>Hold[With[{a=x},{b=x},a]]}
Hold[Hold[With[{a$ = 0}, {b = 0}, a]]]

But let's get back to facts. It appears that (in this case, see bottom of the section) automatic renaming is renaming symbols in arguments from the first one to the last position where potential collisions take place (and this is a problem). Moreover, it is triggered if the problematic symbol (x) appears in the second argument or later.

Here up to the second one but a wasn't there to notice, let's change b = x a:

ClearAll[F];
F[x_] := Hold[With[{a = x}, {b = x a}, a]];
F[0]
Hold[With[{a$ = 0}, {b = 0 a$}, a]]

and if you use x "later", in the third argument, my claim will be held:

ClearAll[F];
F[x_] := Hold[With[{a = x}, {b = x a}, a x]];
F[0]
Hold[With[{a$ = 0}, {b$ = 0 a$}, a$ 0]]

On the other hand this rule seems to apply only to a specific situation where we have a list of assignments:

ClearAll[F1, F2];
F1[x_] := Hold[With[{a = x}, {b = a x} , a]];
F2[x_] := Hold[With[{a = x}, b = a x , a]];
F1[0]
F2[0]
Hold[With[{a$ = 0}, {b = a$ 0}, a]]

Hold[With[{a$ = 0}, b = a$ 0, a$]] (*!!*)

It will happen for a documented syntax too:

ClearAll[F];
F[x_] := Hold[With[{a = x}, a x ]];
F[0]
Hold[With[{a$ = 0}, a$ 0]]

but here we will never face a situation that a scoped symbol (a) appears in an argument subsequent to the minimal position, of x, which triggers renaming.

(*please help with wording ;P *)

Ergo, the new With is not ready for automatic renaming, worth to report.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.