[erlang-questions] Gotta be an easier way...

Jesper Louis Andersen jesper.louis.andersen@REDACTED
Wed Jun 15 19:08:43 CEST 2011


On Mon, Jun 13, 2011 at 23:34, Mike Oxford <moxford@REDACTED> wrote:
> Orig#v1_rec_system_message_user_logon{header=Orig#v1_rec_system_message_user_logon.header#v1_rec_header{route=Orig#v1_rec_system_message_user_logon.header#v1_rec_header.route#v1_rec_route{route_entries=[foo]}}}.

Ugh. You could wrap this up in a helper-function and then call the
helper when you want to do the update. The inliner should make short
work of any trouble there with call overhead.

> Shortening variable names, or writing accessor macros for everything
> are possibilities ... but is there a better way I'm missing?  (Don't
> use nested records is a poor response.)

You may claim that "use something but nested records" is a poor
response. But if you have that requirement there is not much we can
do. Almost every problem with updates in functional programming can be
solved by reordering the structure of your data. In your case you
could either place the variable you are updating close to the
top-level or outright flatten the whole structure completely. You
could also look into alternate data structures and use those.  Nobody
says your structure should reflect an external format, you can just
render it as such.

The main problem is that you need to qualify the records so access can
be resolved at compile time. Avoiding that means either packing the
access away in functions (my first suggestion) or reordering the data
(my second suggestion). Note that matching can help quite a lot
though:

set_route(#system_message { header = Header } = Orig, Val) ->
  Orig#system_message { header = set_route(Header, Val) };
set_route(#rec_header { route = Route } = Orig, Val) ->
  Orig#rec_header { route = set_route(Route, Val) };
set_route(#rec_route { } = Route, Val) ->
  Route#rec_route { route_entries = Val }.

...

But you are probably still better off by altering the structure of the
code. Represent the data in another way and then finally build up your
record structure in one go where everything is correctly set. This
avoids the continual "set this and that in the structure" which is
effective in a language with an ephemeral heap, but is somewhat
wasteful in a language where the heap is persistent -- like Erlang.



-- 
J.



More information about the erlang-questions mailing list