I often write local to ensure a variable does not accidently reuse another definition such as in the example below. Is that a good idea, or is there something more sophisticated I should be doing to test local scoping?
function f(input)
...
p = plot(...)
for i in input.n
local a = ...
local b = ...
local c = ...
local x = ...
local y = ...
local z = ...
plot!(p, x, y, z)
end
...
return MyType(..., p, ...)
end
That feels to me like a weird thing to break out into its own function. I can’t call it plot_my_data because the setup for the plot is outside the loop. I would have to call it like add_data_to_p_plot! and move its definition outside the main function, away from the external related lines.
I guess the main reason probably comes down to function naming. I could move everything starting from p=plot(...) to its own function, but it would have to be named plot_some_aspect_of_my_data, since f in my actual code is already basically named plot_my_data.
The other scenario in which I use this pattern is if I need to calculate another index based on i like local j = 3(i-1)+1. In this case, I need that name j locally for several subsequent calls using outer variables, so I don’t think it makes sense as a separate function.
In any case, making up a new function name any time I need a for loop sounds difficult.
Cannot remember that I ever used local … but would probably consider the fact that the function has grown so long that I need to restrict variable bindings to a smaller subpart of it as the code smell – rule of thumb: don’t need to scroll to see whole function.
To a certain extent, I guess this is a matter of style, and for me personally, one of the big reasons I switched from matlab to julia was that small-function overhead was so huge in matlab (at least at the time, not sure what it’s like now), which gave me a lot of the problems you describe, but with julia I just make a bunch of little functions.
Perhaps a related problem is that there are so many local variables in scope you don’t feel confident you’re not overwriting something important, perhaps these could be organized into something a bit more structured? Say that your x, y, and z represent coordinates. You could then write
for i in input.n
coords = calculate_coordinate_set_i(i)
plot!(p, coords.x, coords.y, coords.z)
end
If other variables across your outer function are similarly contained in structs, NamedTuples, or what-have-you with descriptive names, it seems you could use small variable names like j for indices without it overwriting anything important.
Ultimately though, if this is just you plotting things, and you found a system that works for you, I’d say you’re all good.
Perhaps bunching the local declerations together is easier on the eyes:
function f(input)
...
p = plot(...)
for i in input.n
local a,b,c,x,y,z
a = ...
b = ...
c = ...
x = ...
y = ...
z = ...
plot!(p, x, y, z)
end
...
return MyType(..., p, ...)
end
Perhaps bunching the local declerations together is easier on the eyes:
I would recommend against this. I used to do this in Lua a lot, but it’s easy for the declarations and the assignments to get out of sync, making refactoring harder.
let is basically the same, without having to write the variable names twice.