Skip to main content
Commonmark migration
Source Link

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

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

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

Fixed broken code
Source Link
The Vee
  • 1.8k
  • 13
  • 16

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 intended form of the command for you, for example:

letstar[init_List, expr_] := With[{vars = symbols[init]}, Module[symbols[list] Module[vars, CompoundExpression @@ Join[init, {expr}]]]]] symbols[init_List] := Union@list[[AllUnion@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

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 intended form for you, for example:

letstar[init_List, expr_] := Module[symbols[list], CompoundExpression @@ Join[init, {expr}]] symbols[init_List] := Union@list[[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

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

Post Undeleted by The Vee
Post Deleted by The Vee
Source Link
The Vee
  • 1.8k
  • 13
  • 16

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 intended form for you, for example:

letstar[init_List, expr_] := Module[symbols[list], CompoundExpression @@ Join[init, {expr}]] symbols[init_List] := Union@list[[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