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}
    make_line_rec(T, B, Acc_, X1_, Y1_, X2_, Y2_);
make_line_rec([], _, 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}
    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.

More information about the erlang-questions mailing list