[erlang-questions] Reassigning variables
Matthew Dempsky
matthew@REDACTED
Wed Mar 18 18:56:15 CET 2009
On Wed, Mar 18, 2009 at 3:32 AM, mats cronqvist <masse@REDACTED> wrote:
> Because it's difficult to read, and therefore to maintain.
Here's an actual block of code from the Erlang compiler's v3_core
source:
lc_tq(Line, E, [{generate,Lg,P,G}|Qs0], Mc, St0) ->
{Gs,Qs1} = splitwith(fun is_guard_test/1, Qs0),
{Name,St1} = new_fun_name("lc", St0),
{Head,St2} = new_var(St1),
{Tname,St3} = new_var_name(St2),
LA = lineno_anno(Line, St2),
LAnno = #a{anno=LA},
Tail = #c_var{anno=LA,name=Tname},
{Arg,St4} = new_var(St3),
{Nc,[],St5} = expr({call,Lg,{atom,Lg,Name},[{var,Lg,Tname}]}, St4),
{Guardc,St6} = lc_guard_tests(Gs, St5), %These are always flat!
{Lc,Lps,St7} = lc_tq(Line, E, Qs1, Nc, St6),
{Pc,St8} = list_gen_pattern(P, Line, St7),
{Gc,Gps,St9} = safe(G, St8), %Will be a
function argument!
Fc = function_clause([Arg], LA, {Name,1}),
....
Here's what it would look like with variable reassignment using the
syntax I initially suggested (only replacing St):
lc_tq(Line, E, [{generate,Lg,P,G}|Qs0], Mc, St) ->
{Gs,Qs1} = splitwith(fun is_guard_test/1, Qs0),
{Name,r(St)} = new_fun_name("lc", St),
{Head,r(St)} = new_var(St),
{Tname,r(St)} = new_var_name(St),
LA = lineno_anno(Line, St),
LAnno = #a{anno=LA},
Tail = #c_var{anno=LA,name=Tname},
{Arg,r(St)} = new_var(St),
{Nc,[],r(St)} = expr({call,Lg,{atom,Lg,Name},[{var,Lg,Tname}]}, St),
{Guardc,r(St)} = lc_guard_tests(Gs, St), %These are always flat!
{Lc,Lps,r(St)} = lc_tq(Line, E, Qs1, Nc, St),
{Pc,r(St)} = list_gen_pattern(P, Line, St),
{Gc,Gps,r(St)} = safe(G, St), %Will be a
function argument!
Fc = function_clause([Arg], LA, {Name,1}),
....
I don't think this is any more difficult to read or maintain than the
current code. There's no extra information imparted by "St7" than
just "St"; the reader doesn't care that it's the result from the
seventh state-mutating function call, just that it's the most recent
state variable. Also, this code has the benefit that if an extra
state-mutating function needs to be introduced, it doesn't necessitate
renumbering a dozen variables: it could be disasterous if (e.g.) a
later use of St5 isn't updated to St6.
Actually, I just noticed that the above two blocks of code aren't
identical, because "LA = lineno_anno(Line, St2)" happens after St3 has
been defined. I doubt this is intentional and rather just a (in this
case harmless) bug along the lines of mis-renumbering like I've been
warning about.
More information about the erlang-questions
mailing list