[erlang-questions] Tuples referencing each other problem

Mikael Pettersson mikpelinux@REDACTED
Sun Sep 17 10:32:09 CEST 2017


Grzegorz Junka writes:
 > Is it possible to create two tuples that reference each other in Erlang? 
 > Something like:
 > 
 > T1 = {T2}
 > T2 = {T1}
 > 
 > My understanding is that when using pointers (i.e. in C++) one needs to 
 > mutate the first tuple in order to store the reference to the second 
 > tuple once it has been created.
 > 
 > This is of course a generalization of a more specific problem of 
 > creating liked structures like a double linked list or a tree with leafs 
 > containing links to each other. Are there any techniques that would 
 > allow creating algorithms operating on such structures in Erlang?

Short answer: No, you cannot create circular data structures in
Erlang.

Erlang "terms" are made up of leafs (pids, ports, numbers, atoms,
the empty list [], binaries, refs) and aggregates (list cells,
tuples, function closures, maps).  Leafs do not refer to other
terms, and aggregates are write-once: they're fully initialized
when created and then remain immutable.  When you see an "update"
operation like setelement/2, it actually creates a copy where
the target element has been changed, leaving the old term unchanged.

There are various ways to simulate assignment:

1. Put labels in your data where you'd otherwise have direct
   references, and have a mapping from labels to terms.  Update
   that mapping when needed -- but you also have to pass it around
   so the update is seen by subsequent code.

   Erlang now has a built-in "map" type that provides such mappings,
   otherwise there are tree and list based mapping ADTs in the standard
   library, or you implement your own.

2. Use an ETS table.  This is an external (to your process) bag
   of Erlang terms, where you can insert/lookup/delete terms.
   This is a stateful object, so inserts/deletes update the
   existing table rather than creating a copy with that change.

   You still have to "indirect" via labels, but you avoid the
   need for passing around an updated mapping.

3. Use a helper process that keeps the state and allows you to
   query or update it through messages.  Semantically this is
   very similar to an ETS table.

4. You can use the process dictionary, but it's not recommended
   as it's a shared resource with both the standard libraries and
   any other code that might have the same idea.



More information about the erlang-questions mailing list