optimal way to append an element in a list inside a map

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
12 messages Options
Reply | Threaded
Open this post in threaded view
|

optimal way to append an element in a list inside a map

Caragea Silviu
Hello,

Having a map where the value of each element it's a list :

#{ 1 => [], 2 => [], ... n => []}

and you need to append elements in the list for a specific key, what's the most optimal way to do this without copying the lists and the map inside the VM lot of times ?

Anything better than the following solution:

append_element(Key, Value, Map) ->
    case maps:find(Key, Map) of
        {ok, V} ->
            maps:put(Key, [Value | V], Map);
        _ ->
            maps:put(Key, [Value], Map)
    end.

Kind regards,
Silviu

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: optimal way to append an element in a list inside a map

Dmitry Kolesnikov-2
Hello,

Premature optimisation is an evil ;-)

I would use the following syntax:
```
append(Key, Value, Map) ->
   List = case Map of
      #{Key := Tail} ->
         [Value | Tail];
      _ ->
         [Value]
   end,
   Map#{Key => List}.
```

Lists are not copied they are referenced. Maps… Hmm, I am not sure. I hope the implementation is smart enough to keep reference as well.

- Dmitry


> On 29 Aug 2017, at 20.34, Caragea Silviu <[hidden email]> wrote:
>
> Hello,
>
> Having a map where the value of each element it's a list :
>
> #{ 1 => [], 2 => [], ... n => []}
>
> and you need to append elements in the list for a specific key, what's the most optimal way to do this without copying the lists and the map inside the VM lot of times ?
>
> Anything better than the following solution:
>
> append_element(Key, Value, Map) ->
>     case maps:find(Key, Map) of
>         {ok, V} ->
>             maps:put(Key, [Value | V], Map);
>         _ ->
>             maps:put(Key, [Value], Map)
>     end.
>
> Kind regards,
> Silviu
> _______________________________________________
> erlang-questions mailing list
> [hidden email]
> http://erlang.org/mailman/listinfo/erlang-questions

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: optimal way to append an element in a list inside a map

Brujo Benavides-3
I think this might be what you are looking for:

append(Key, Value, Map) ->
maps:update_with(Key, fun(Tail) -> [Value | Tail] end, [], Map).

On Aug 29, 2017, at 15:19, Dmitry Kolesnikov <[hidden email]> wrote:

Hello,

Premature optimisation is an evil ;-)

I would use the following syntax:
```
append(Key, Value, Map) ->
  List = case Map of
     #{Key := Tail} ->
        [Value | Tail];
     _ ->
        [Value]
  end,
  Map#{Key => List}.
```

Lists are not copied they are referenced. Maps… Hmm, I am not sure. I hope the implementation is smart enough to keep reference as well.

- Dmitry


On 29 Aug 2017, at 20.34, Caragea Silviu <[hidden email]> wrote:

Hello,

Having a map where the value of each element it's a list :

#{ 1 => [], 2 => [], ... n => []}

and you need to append elements in the list for a specific key, what's the most optimal way to do this without copying the lists and the map inside the VM lot of times ?

Anything better than the following solution:

append_element(Key, Value, Map) ->
   case maps:find(Key, Map) of
       {ok, V} ->
           maps:put(Key, [Value | V], Map);
       _ ->
           maps:put(Key, [Value], Map)
   end.

Kind regards,
Silviu
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions


_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: optimal way to append an element in a list inside a map

Dmytro Lytovchenko
In reply to this post by Dmitry Kolesnikov-2


2017-08-29 20:19 GMT+02:00 Dmitry Kolesnikov <[hidden email]>:
Hello,

Premature optimisation is an evil ;-)

I would use the following syntax:
```
append(Key, Value, Map) ->
   List = case Map of
      #{Key := Tail} ->
         [Value | Tail];
      _ ->
         [Value]
   end,
   Map#{Key => List}.
```

Lists are not copied they are referenced. Maps… Hmm, I am not sure. I hope the implementation is smart enough to keep reference as well.

In BEAM any object which does not fit into a machine register (such as a list or a map) will be placed on heap and a pointer will be used instead. But prepending to a list will change the list pointer value (the pointer to list head will change, the remaining tail elements will not move and will not change). This requires writing the new head into the map value. And this will incur a map update, which most likely will rebuild the map. I'm almost sure that the optimization possibilities for this are very limited and are similar to tuple optimizations (i.e. works only at creation time).
 

- Dmitry


> On 29 Aug 2017, at 20.34, Caragea Silviu <[hidden email]> wrote:
>
> Hello,
>
> Having a map where the value of each element it's a list :
>
> #{ 1 => [], 2 => [], ... n => []}
>
> and you need to append elements in the list for a specific key, what's the most optimal way to do this without copying the lists and the map inside the VM lot of times ?
>
> Anything better than the following solution:
>
> append_element(Key, Value, Map) ->
>     case maps:find(Key, Map) of
>         {ok, V} ->
>             maps:put(Key, [Value | V], Map);
>         _ ->
>             maps:put(Key, [Value], Map)
>     end.
>
> Kind regards,
> Silviu
> _______________________________________________
> erlang-questions mailing list
> [hidden email]
> http://erlang.org/mailman/listinfo/erlang-questions

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions


_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: optimal way to append an element in a list inside a map

Caragea Silviu
Hmm,

Basically what you are saying is that any update over a map requires rebuilding of the entire map ? I doubt as time implementation seems so lame..

Any way that we con confirm or not this theory ?

Silviu

On Tue, Aug 29, 2017 at 9:34 PM, Dmytro Lytovchenko <[hidden email]> wrote:


2017-08-29 20:19 GMT+02:00 Dmitry Kolesnikov <[hidden email]>:
Hello,

Premature optimisation is an evil ;-)

I would use the following syntax:
```
append(Key, Value, Map) ->
   List = case Map of
      #{Key := Tail} ->
         [Value | Tail];
      _ ->
         [Value]
   end,
   Map#{Key => List}.
```

Lists are not copied they are referenced. Maps… Hmm, I am not sure. I hope the implementation is smart enough to keep reference as well.

In BEAM any object which does not fit into a machine register (such as a list or a map) will be placed on heap and a pointer will be used instead. But prepending to a list will change the list pointer value (the pointer to list head will change, the remaining tail elements will not move and will not change). This requires writing the new head into the map value. And this will incur a map update, which most likely will rebuild the map. I'm almost sure that the optimization possibilities for this are very limited and are similar to tuple optimizations (i.e. works only at creation time).
 

- Dmitry


> On 29 Aug 2017, at 20.34, Caragea Silviu <[hidden email]> wrote:
>
> Hello,
>
> Having a map where the value of each element it's a list :
>
> #{ 1 => [], 2 => [], ... n => []}
>
> and you need to append elements in the list for a specific key, what's the most optimal way to do this without copying the lists and the map inside the VM lot of times ?
>
> Anything better than the following solution:
>
> append_element(Key, Value, Map) ->
>     case maps:find(Key, Map) of
>         {ok, V} ->
>             maps:put(Key, [Value | V], Map);
>         _ ->
>             maps:put(Key, [Value], Map)
>     end.
>
> Kind regards,
> Silviu
> _______________________________________________
> erlang-questions mailing list
> [hidden email]
> http://erlang.org/mailman/listinfo/erlang-questions

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions



_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: optimal way to append an element in a list inside a map

scott ribe
In reply to this post by Dmytro Lytovchenko

> On Aug 29, 2017, at 12:34 PM, Dmytro Lytovchenko <[hidden email]> wrote:
>
>
>
> 2017-08-29 20:19 GMT+02:00 Dmitry Kolesnikov <[hidden email]>:
> Hello,
>
> Premature optimisation is an evil ;-)
>
> I would use the following syntax:
> ```
> append(Key, Value, Map) ->
>    List = case Map of
>       #{Key := Tail} ->
>          [Value | Tail];
>       _ ->
>          [Value]
>    end,
>    Map#{Key => List}.
> ```
>
> Lists are not copied they are referenced. Maps… Hmm, I am not sure. I hope the implementation is smart enough to keep reference as well.
>
> In BEAM any object which does not fit into a machine register (such as a list or a map) will be placed on heap and a pointer will be used instead. But prepending to a list will change the list pointer value (the pointer to list head will change, the remaining tail elements will not move and will not change). This requires writing the new head into the map value. And this will incur a map update, which most likely will rebuild the map. I'm almost sure that the optimization possibilities for this are very limited and are similar to tuple optimizations (i.e. works only at creation time).

Actually, it's perfectly possible to optimize the map insertion in a way analogous to the list prepending. A new root will be created, sharing old structure. If you think of some tree, then in fact new nodes are created from the leaf value you just added back up to the root, so not as cheap as list prepending, but way cheaper than copying the tree.

--
Scott Ribe
[hidden email]
(303) 722-0567

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: optimal way to append an element in a list inside a map

Vlad Dumitrescu-2
In reply to this post by Caragea Silviu
On Tue, Aug 29, 2017 at 8:41 PM, Caragea Silviu <[hidden email]> wrote:
Hmm,
Basically what you are saying is that any update over a map requires rebuilding of the entire map ? I doubt as time implementation seems so lame.. 

Well, Erlang is a functional language and as such, you can't update any data structure in place. Updates create a new data structure and others may still have references to the original. Always. For lists, you can reuse the original list as the tail. For tuples, you have to copy the top level. For maps, it depends: the implementation is a HAMT structure, which means that it depends on the contents how much will be rewritten when updating; I don't know what the worst case is.

Whatever the case, there will be a new map data structure created. 

regards,
Vlad

 
Any way that we con confirm or not this theory ?

Silviu

On Tue, Aug 29, 2017 at 9:34 PM, Dmytro Lytovchenko <[hidden email]> wrote:


2017-08-29 20:19 GMT+02:00 Dmitry Kolesnikov <[hidden email]>:
Hello,

Premature optimisation is an evil ;-)

I would use the following syntax:
```
append(Key, Value, Map) ->
   List = case Map of
      #{Key := Tail} ->
         [Value | Tail];
      _ ->
         [Value]
   end,
   Map#{Key => List}.
```

Lists are not copied they are referenced. Maps… Hmm, I am not sure. I hope the implementation is smart enough to keep reference as well.

In BEAM any object which does not fit into a machine register (such as a list or a map) will be placed on heap and a pointer will be used instead. But prepending to a list will change the list pointer value (the pointer to list head will change, the remaining tail elements will not move and will not change). This requires writing the new head into the map value. And this will incur a map update, which most likely will rebuild the map. I'm almost sure that the optimization possibilities for this are very limited and are similar to tuple optimizations (i.e. works only at creation time).
 

- Dmitry


> On 29 Aug 2017, at 20.34, Caragea Silviu <[hidden email]> wrote:
>
> Hello,
>
> Having a map where the value of each element it's a list :
>
> #{ 1 => [], 2 => [], ... n => []}
>
> and you need to append elements in the list for a specific key, what's the most optimal way to do this without copying the lists and the map inside the VM lot of times ?
>
> Anything better than the following solution:
>
> append_element(Key, Value, Map) ->
>     case maps:find(Key, Map) of
>         {ok, V} ->
>             maps:put(Key, [Value | V], Map);
>         _ ->
>             maps:put(Key, [Value], Map)
>     end.
>
> Kind regards,
> Silviu
> _______________________________________________
> erlang-questions mailing list
> [hidden email]
> http://erlang.org/mailman/listinfo/erlang-questions

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions



_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions



_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: optimal way to append an element in a list inside a map

Sverker Eriksson-4
In reply to this post by Caragea Silviu
Maps have two implementations depending on number of keys.

Small maps (<= 32 keys) are basically a key-tuple and a value tuple.
Updating the value of an existing key will copy the value-tuple
while reusing the key-tuple.

Large maps (> 32 keys) are basically a tree (HAMT).
All nodes from the root to the one containing the key must be copied
while all other nodes can be reused.

/Sverker

On 08/29/2017 08:41 PM, Caragea Silviu wrote:
Hmm,

Basically what you are saying is that any update over a map requires
rebuilding of the entire map ? I doubt as time implementation seems so
lame..

Any way that we con confirm or not this theory ?

Silviu

On Tue, Aug 29, 2017 at 9:34 PM, Dmytro Lytovchenko <
[hidden email]> wrote:


2017-08-29 20:19 GMT+02:00 Dmitry Kolesnikov [hidden email]:

Hello,

Premature optimisation is an evil ;-)

I would use the following syntax:
```
append(Key, Value, Map) ->
   List = case Map of
      #{Key := Tail} ->
         [Value | Tail];
      _ ->
         [Value]
   end,
   Map#{Key => List}.
```

Lists are not copied they are referenced. Maps… Hmm, I am not sure. I
hope the implementation is smart enough to keep reference as well.

In BEAM any object which does not fit into a machine register (such as a
list or a map) will be placed on heap and a pointer will be used instead.
But prepending to a list will change the list pointer value (the pointer to
list head will change, the remaining tail elements will not move and will
not change). This requires writing the new head into the map value. And
this will incur a map update, which most likely will rebuild the map. I'm
almost sure that the optimization possibilities for this are very limited
and are similar to tuple optimizations (i.e. works only at creation time).


- Dmitry


On 29 Aug 2017, at 20.34, Caragea Silviu [hidden email] wrote:

Hello,

Having a map where the value of each element it's a list :

#{ 1 => [], 2 => [], ... n => []}

and you need to append elements in the list for a specific key, what's
the most optimal way to do this without copying the lists and the map
inside the VM lot of times ?
Anything better than the following solution:

append_element(Key, Value, Map) ->
    case maps:find(Key, Map) of
        {ok, V} ->
            maps:put(Key, [Value | V], Map);
        _ ->
            maps:put(Key, [Value], Map)
    end.

Kind regards,
Silviu
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions



      

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions


_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: optimal way to append an element in a list inside a map

Caragea Silviu
Hello,

Thanks for clarification. I thought that in background erlang can see when there is no other reference to the original map/list (for example in case of accumulator inside a recursive fun) and will append to the original object while updating the reference instead of making partial copy.

Silviu

On Tue, Aug 29, 2017 at 10:01 PM, Sverker Eriksson <[hidden email]> wrote:
Maps have two implementations depending on number of keys.

Small maps (<= 32 keys) are basically a key-tuple and a value tuple.
Updating the value of an existing key will copy the value-tuple
while reusing the key-tuple.

Large maps (> 32 keys) are basically a tree (HAMT).
All nodes from the root to the one containing the key must be copied
while all other nodes can be reused.

/Sverker

On 08/29/2017 08:41 PM, Caragea Silviu wrote:
Hmm,

Basically what you are saying is that any update over a map requires
rebuilding of the entire map ? I doubt as time implementation seems so
lame..

Any way that we con confirm or not this theory ?

Silviu

On Tue, Aug 29, 2017 at 9:34 PM, Dmytro Lytovchenko <
[hidden email]> wrote:

2017-08-29 20:19 GMT+02:00 Dmitry Kolesnikov [hidden email]:

Hello,

Premature optimisation is an evil ;-)

I would use the following syntax:
```
append(Key, Value, Map) ->
   List = case Map of
      #{Key := Tail} ->
         [Value | Tail];
      _ ->
         [Value]
   end,
   Map#{Key => List}.
```

Lists are not copied they are referenced. Maps… Hmm, I am not sure. I
hope the implementation is smart enough to keep reference as well.

In BEAM any object which does not fit into a machine register (such as a
list or a map) will be placed on heap and a pointer will be used instead.
But prepending to a list will change the list pointer value (the pointer to
list head will change, the remaining tail elements will not move and will
not change). This requires writing the new head into the map value. And
this will incur a map update, which most likely will rebuild the map. I'm
almost sure that the optimization possibilities for this are very limited
and are similar to tuple optimizations (i.e. works only at creation time).


- Dmitry


On 29 Aug 2017, at 20.34, Caragea Silviu [hidden email] wrote:

Hello,

Having a map where the value of each element it's a list :

#{ 1 => [], 2 => [], ... n => []}

and you need to append elements in the list for a specific key, what's
the most optimal way to do this without copying the lists and the map
inside the VM lot of times ?
Anything better than the following solution:

append_element(Key, Value, Map) ->
    case maps:find(Key, Map) of
        {ok, V} ->
            maps:put(Key, [Value | V], Map);
        _ ->
            maps:put(Key, [Value], Map)
    end.

Kind regards,
Silviu
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions


      

      

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions



_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: optimal way to append an element in a list inside a map

Jesper Louis Andersen-2
If you measure and find the map to be too slow for you, the use case you have where the contents are ephemeral suggest you should look into using an ETS table of type bag or ordered_bag. You can get some really fast code by using this if you don't need the persistence the map provides.

I'd measure first though. Chances are the maps are plenty fast. You can always encapsulate the implementation so you can subst in ETS later if need be.

On Tue, Aug 29, 2017 at 9:16 PM Caragea Silviu <[hidden email]> wrote:
Hello,

Thanks for clarification. I thought that in background erlang can see when there is no other reference to the original map/list (for example in case of accumulator inside a recursive fun) and will append to the original object while updating the reference instead of making partial copy.

Silviu

On Tue, Aug 29, 2017 at 10:01 PM, Sverker Eriksson <[hidden email]> wrote:
Maps have two implementations depending on number of keys.

Small maps (<= 32 keys) are basically a key-tuple and a value tuple.
Updating the value of an existing key will copy the value-tuple
while reusing the key-tuple.

Large maps (> 32 keys) are basically a tree (HAMT).
All nodes from the root to the one containing the key must be copied
while all other nodes can be reused.

/Sverker

On 08/29/2017 08:41 PM, Caragea Silviu wrote:
Hmm,

Basically what you are saying is that any update over a map requires
rebuilding of the entire map ? I doubt as time implementation seems so
lame..

Any way that we con confirm or not this theory ?

Silviu

On Tue, Aug 29, 2017 at 9:34 PM, Dmytro Lytovchenko <
[hidden email]> wrote:

2017-08-29 20:19 GMT+02:00 Dmitry Kolesnikov [hidden email]:

Hello,

Premature optimisation is an evil ;-)

I would use the following syntax:
```
append(Key, Value, Map) ->
   List = case Map of
      #{Key := Tail} ->
         [Value | Tail];
      _ ->
         [Value]
   end,
   Map#{Key => List}.
```

Lists are not copied they are referenced. Maps… Hmm, I am not sure. I
hope the implementation is smart enough to keep reference as well.

In BEAM any object which does not fit into a machine register (such as a
list or a map) will be placed on heap and a pointer will be used instead.
But prepending to a list will change the list pointer value (the pointer to
list head will change, the remaining tail elements will not move and will
not change). This requires writing the new head into the map value. And
this will incur a map update, which most likely will rebuild the map. I'm
almost sure that the optimization possibilities for this are very limited
and are similar to tuple optimizations (i.e. works only at creation time).


- Dmitry


On 29 Aug 2017, at 20.34, Caragea Silviu [hidden email] wrote:

Hello,

Having a map where the value of each element it's a list :

#{ 1 => [], 2 => [], ... n => []}

and you need to append elements in the list for a specific key, what's
the most optimal way to do this without copying the lists and the map
inside the VM lot of times ?
Anything better than the following solution:

append_element(Key, Value, Map) ->
    case maps:find(Key, Map) of
        {ok, V} ->
            maps:put(Key, [Value | V], Map);
        _ ->
            maps:put(Key, [Value], Map)
    end.

Kind regards,
Silviu
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions


      

      

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions


_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: optimal way to append an element in a list inside a map

Richard A. O'Keefe-2
In reply to this post by Caragea Silviu

On 30/08/17 5:34 AM, Caragea Silviu wrote:

> Having a map where the value of each element is a list :
>
> #{ 1 => [], 2 => [], ... n => []}
>
> and you need to append elements in the list for a specific key,

You write "append", and to append an element X to a list L is to
compute L ++ [X] somehow.  But your sample code computes
[X] ++ L (as [X|L]), which already does not copy L, and is not
appending but prepending.

     case Map
       of #{ Key := List } -> Map#{Key := [Value|List]}
        ; _                -> Map#{Key => [Value]}
     end

does what you appear to want in native syntax.  (Tested.)
What performance difference there may be between this and
your example code is a quality-of-implementation issue
discoverable by benchmarking.

To repeat, it doesn't copy List.
But it has to copy Map in order to change it.
Parts of the new Map will share structure with the old one,
but how much and how much of a cost the copying is will be
a quality-of-implementation issue and depends on the number of
keys in the Map.

It would help to know more about the problem you are actually
trying to solve.

BTW "most optimal" is redundant; "optimal" already means "best".

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: optimal way to append an element in a list inside a map

Richard A. O'Keefe-2
In reply to this post by Caragea Silviu


On 30/08/17 6:41 AM, Caragea Silviu wrote:
> Hmm,
>
> Basically what you are saying is that any update over a map requires
> rebuilding of the entire map ?

It doesn't take much poking around on the Web before you discover
that Erlang maps use "a HAMT (Hash-Array Mapped Trie) internally once
the map grows enough. It is a clever data structure which combines the
properties of a hash table with a (level compressed) trie to provide
fast lookup as well as persistence. This is the same data structure
languages like Clojure, Scala and Haskell (unordered-containers) use.
They were designed by the now late Phil Bagwell and the Erlang variant
leans itself up against the work of Rich Hickey in Clojure."
-- Jesper L. Andersen, at
https://medium.com/@jlouis666/breaking-erlang-maps-1-31952b8729e6

Large maps in Erlang are therefore trees with fairly wide nodes,
but updating a map WON'T copy the whole thing.

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions