I often find myself writing code that looks a bit like this:
f[x_Integer] :=
With[
{
range = Range[2] + x
},
With[
{
a = range[[1]],
b = range[[2]],
c = g[range]
},
h[a,b,c]
]
];
It would be nice if I could avoid With
s and just write
f[x_Integer] :=
Let[
range = Range[2] + x,
{a,b} = range,
c = g[range]
,
h[a,b,c]
];
which would then automatically expand to the above at definition time.
What I'm asking is a bit similar to this question. There are additional requirements however. The new scoping construct (Let
in the above) should:
- Group sequential disjoint assignments into single
With
s. - Thread over
List
assignments.
Of course, it should not evaluate the left-hand-sides and the right-hand-sides of the assignments while expanding to With
s.
Any proposals for such a scoping construct? (I'll post my version soon).
f[x_Integer] := h[Sequence@@#,g@#]&@(Range[2]+x)
$\endgroup$With
rather than preserving a higher abstraction such asLetL
? $\endgroup$With
overModule
? Assignments such as{a,b} = range
are simpler with the latter. $\endgroup$LetL
, which doesn't do the two points I mentioned (Leonid's answer below does).Module
doesn't allow you to do threaded assignments in the first argument, forcing you to writeModule[{a,b},{a,b}=Range[2];...]
, which is duplication I don't like. Also, it'd like to inject into held expressions -- another reason not to go withModule
. $\endgroup$With
in Mathematica 10.3 and above: e.g.With[{c = d}, {b = c}, {a = b}, a]
(You'll have to also tolerate the red syntax coloring in the front end, or turn it off manually) [and I just realized that it doesn't satisfy your second requirement of threading overList
assignments] $\endgroup$