[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

    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