# Is there any way to implement a "sequential" With[] in Mathematica? [duplicate]

I want the equivalent of Scheme's let*, or basically, a sequential With that works like this:

With[{a = 0,
a = a + 1,
a = a + 1},
a]


Is there any way to implement this? Everything I tried with Hold/Unevaluated/etc. led nowhere.

• Interesting v10: wolfram.com/mathematica/new-in-10/inactive-objects/… Commented Mar 7, 2016 at 10:11
• Commented Mar 7, 2016 at 10:12
• Add bracing for each level. In Mathematica 10.something we started to allow this. In[655]:= With[{a = 0}, {a = a + 1}, {a = a + 1}, a] Out[655]= 2. There is some amount of reddening in the user interface because it has not yet caught up to this change (fixing that is not entirely trivial). Commented Mar 7, 2016 at 16:48
• @DanielLichtblau: Thanks a lot for mentioning that, But ouch, that red is nasty! Any idea when it might get fixed? I actually use the syntax highlighting to help me figure out what variables are declared properly... Commented Mar 7, 2016 at 19:19
• @unlikely: Thanks a ton for the links, those are super helpful! Commented Mar 7, 2016 at 19:20

This is outside the scope of With. The documentation says:

With[{x=x₀, y=y₀, ...}, expr]

specifies that all occurrences of the symbols x, y, ... in expr should be replaced by x₀, y₀, ...

So even if there was a "sequential" With, it wouldn't be able to understand a = a+1 as updating the value of a. It would always just be a replace rule.

I think you'd be best off with a Module:

Module[{a},
a = 0;
a = a+1;
a = a+1;
a]


You can write your own command which rewrites the form of the command for you, for example:

letstar[init_List, expr_] :=
With[{vars = symbols[init]},
Module[vars, CompoundExpression @@ Join[init, {expr}]]]
symbols[init_List] := Union@Hold[init][[1, All, 1]]
SetAttributes[symbols, HoldFirst]
SetAttributes[letstar, HoldFirst]


This assumes that the first argument of letstar is a list of assignments (this is not checked) and holds its form so that they are not performed. Instead, they are passed to symbols which only extracts the left-hand sides and lists unique variables appearing in them. This is passed to a Module as the local variables, the init block is converted into a compound expression and finally expr is evaluated. So if you call

letstar[{a = 0, a = a + 1, a = a + 1}, a]


this gets internally transformed to

Module[{a}, a = 0; a = a+1; a = a+1; a]


and returns

2