How to correctly implement in a new function the scoping behavior of Table, Sum and other commands that use Block to localize iterators?
You can safely ignore the warning and red highlighting. It simply tells you that the variable will be injected into Block
by the top-level rule (your function), rather than being the actual symbol originally present in Block
's declaration list. Which is exactly what you want here.
In most cases, things like that happen due to a programmer's mistake, which is why there is a warning. But in your case, you do want to use Block
exactly like that. Also, while there is a warning, in the case of Block
the outer SetDelayed
won't attempt to rename variables, since Block
is a dynamic rather than lexical scoping construct - so you don't have to worry about that either.
As to the number of calls, one thing you can do to reduce them is to replace
mySum[arg_, {index_Symbol, limits___}] := ...
with
mySum[arg_, {index_Symbol, limits___}] /; ! ValueQ[evaluatedarg] := ...
This would cut the number of calls in half, for your example.