views:

248

answers:

1

The Erlang digraphs module surprised me by mutating state.

When dealing with other data structure modules in Erlang, for instance the sets module, the instance of the data structure passed in, is unmodified. The function returns a new, altered version e.g.

>S = sets:new().
>sets:size(S).
0
>T = sets:add_element(S, "element").
>sets:size(S).
0
>sets:size(T).
1

This is not the behaviour when dealing with the digraph module.

>G = digraph:new().
>digraph:no_vertices(G).
0
>digraph:add_vertex(G, "vertex").
>digraph:no_vertices(G).
1

Firstly, why is the digraph library different in this respect?

Secondly, and more importantly, how is the digraph module adding new state against an existing binding?

I assume the state is being stored in another process which the digraph module is identifying using the existing and unaltered binding G. Is this the case? Or are there other ways of modifying state associated with a binding?

+7  A: 
  1. Probably for efficiency
  2. It's using ETS to store the digraph. The return value from the new are actually references to ets tables.

Run toolbar:start(). from your erlang shell and open up the table visualizer application - you'll see a set of ets tables for the digraph utility.

edges
vertices
neighbours

The values in the return value from the digraph:new call are the ets table ids of these tables...

Alan Moore
Thanks, I could not find any processes that looked like they were dealing with digraphs.Are there any conventions in erlang modules that tell you that state is being stored outside the current process?
John Kane
No I don't think there is. But when I saw the return value from digraph:new() it did look remarkably like a reference to something else and the usual place to store "something else" is ets...
Alan Moore
I remember that in former digraph documentation ets was mentioned just in doc in Description part, but now it is not.
Hynek -Pichi- Vychodil