# Sometimes I miss destructively updating local variables

Richard A. O'Keefe <>
Fri Jul 7 08:21:23 CEST 2006

"James Hague" <> wrote
(a recursive function which can be rewritten as)

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

Using the "let loop" notation proposed earlier for generalised folds,
this could be

make_line_rec(Attrs, B, Acc, X1, Y1, X2, Y2) ->
let {List,Xa,Ya,Xb,Yb} = {Acc,X1,Y1,X2,Y2} then
case Tag of
of x1 -> {List,parse_units(B, Ofs, Len),Ya,Xb,Yb}
;  x2 -> {List,Xa,parse_units(B, Ofs, Len),Xb,Yb}
;  y1 -> {List,Xa,Ya,parse_units(B, Ofs, Len),Yb}
;  y2 -> {List,Xa,Ya,Xb,parse_units(B, Ofs, Len)}
;  _  ->
case is_attr(Tag)
of true  -> {get_attr(Attr,B)|List],Xa,Ya,Xb,Yb}
;  false -> {List,Xa,Ya,Xb,Yb}
end
end
for Attr = {Tag,Ofs,Len} <- Attrs
in  {line,List,Xa,Ya,Xb,Yb}.

Now there _is_ some redundancy here, but not as much.

I'm not sure that listing the unchanged variables is a bad thing
as long as there aren't too many of them.

It _would_ be possible to extend Erlang syntax with
"Variable := Expression", meaning to introduce a new binding for
Variable, but there are a lot of details to work out.