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 Withs 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
Withs. - Thread over
Listassignments.
Of course, it should not evaluate the left-hand-sides and the right-hand-sides of the assignments while expanding to Withs.
Any proposals for such a scoping construct? (I'll post my version soon).
f[x_Integer] := h[Sequence@@#,g@#]&@(Range[2]+x)– Bob Hanlon Nov 05 '14 at 14:24Withrather than preserving a higher abstraction such asLetL? – Mr.Wizard Nov 05 '14 at 14:56WithoverModule? Assignments such as{a,b} = rangeare simpler with the latter. – Mr.Wizard Nov 05 '14 at 15:00LetL, which doesn't do the two points I mentioned (Leonid's answer below does).Moduledoesn'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. – Teake Nutma Nov 05 '14 at 15:07WithvsModule,Withis cleaner (manifestly no side effects), when one knows that variables won't change in the body. – Leonid Shifrin Nov 05 '14 at 15:07Within 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 overListassignments] – QuantumDot May 04 '16 at 20:03