[erlang-questions] Dictionary strategy of last value wins
Sun Jun 22 20:06:39 CEST 2014
I’m implementing a library using dictionaries and I’ve noticed that all the
dictionary alternatives use imperative-style initialization semantics. Proplists were
introduced to allow efficient shadowing of environments and defaults.
Pushing a value on the front of a proplist makes the first value encountered
be the current value. You can then pop contexts and reveal the older values
efficiently in a functional programming style.
Dictionaries use hash-like semantics of last value wins in an imperative
assignment that clobbers old values (and loses them forever) thus making
them non-functional and non-persistent. I assume initialization of dictionaries
are kept imperative for consistency / efficiency, but it makes the two styles
of initialization incompatible (but keeps the internal semantics of each
The recommended technique for maps is to set a default dictionary and
then the shadowing dictionary and merge them. I guess this leads to a
functional style of a stack of maps for shadowing contexts, but this approach
is only recommended as overcoming default initialization. In recent code,
I’ve had to use different semantics for defaulted values vs user-specified
values and having a dictionary meant I couldn’t tell whether the current
value was an implicit default or an explicit choice after the initialization
phase had completed.
Do others build proplists and then reverse them when initializing a dictionary?
(This seems very imperative, having to maintain your own data versions:
proplist and dictionary init list, especially if you want shadowing semantics
and need to go back to the source context and initialize subsequent dictionaries).
Or do you maintain a stack of dictionaries and do a cascading search until
a value is found? This approach allows context labeling and thus you could
know if a value was explicit or implicitly defaulted.
Or do you just change to an imperative style for your code when you start
thinking with dictionaries (or have you not noticed the difference)?
My new library is supposed to allow selection of implementation without
change to the higher-level logic. I suppose I am going to have to provide
‘proplist (functional)’ and ‘last wins (imperative)’ options for initialization
of the underlying implementation (and do proper initialization in all cases).
My current approach is to stick with a functional style of programming
and use proplist semantics on initialization of my object wrappers around
dictionaries (dict, orddict, vbisect; maps in future; possibly will add
proplists and records as options as well, and I suppose arrays could
be used). The current overhead expense is that I have to scan the init
list while constructing the dictionary doing lookups to see if a value is
already set and skip it in the case of an earlier definition (I also do this
because I sometimes need to validate the datatypes to ensure that
constructed dictionaries use legal types on all input — I could switch
to a faster initialization in cases where datatype doesn’t matter by
reversing the list, assuming the list size is never ginormous).
More information about the erlang-questions