Sometimes I miss destructively updating local variables

James Hague <>
Fri Jul 7 05:42:48 CEST 2006


Often I find myself writing a function that's just a case statement
where each branch ends with a tail-recursive call.  Here's an example
pulled from working code:

make_line_rec([{Tag,Ofs,Len}=Attr|T], B, Acc, X1, Y1, X2, Y2) ->
   case Tag of
      x1 -> make_line_rec(T, B, Acc, parse_units(B, Ofs, Len), Y1, X2, Y2);
      y1 -> make_line_rec(T, B, Acc, X1, parse_units(B, Ofs, Len), X2, Y2);
      x2 -> make_line_rec(T, B, Acc, X1, Y1, parse_units(B, Ofs, Len), Y2);
      y2 -> make_line_rec(T, B, Acc, X1, Y1, X2, parse_units(B, Ofs, Len));
      _ ->
         case is_attr(Tag) of
            true  -> make_line_rec(T, B, [get_attr(Attr, B)|Acc], X1,
Y1, X2, Y2);
            false -> make_line_rec(T, B, Acc, X1, Y1, X2, Y2)
         end
   end;
make_line_rec([], _, Acc, X1, Y1, X2, Y2) -> {line, Acc, X1, Y1, X2, Y2}.

What bugs me is having to list all the variables in the make_line_rec
call.  In reality, this function is just a while loop, and each time
through the loop one of a set of local variables (Acc, X1, Y1, X2, Y2)
is updated.  Before any functional purists jump on me, this is EXACTLY
how the generated BEAM code works.  Those variables live in registers,
and each make_line_rec "call" destructively updates one of those
values, then jumps to the start of the function.

In fact, I could write a language with destructive updates for locals,
and the generated code would be fast and efficient--and perfectly
normal--Erlang.  The difference being that all the listing of
parameters goes away, and the function is less dense and simpler to
maintain.

How do other Erlang programmers deal with this?

James



More information about the erlang-questions mailing list