[erlang-questions] *current* value?
Thu Oct 18 00:13:28 CEST 2007
> Hopefully this follow-up doesn't make me sound like a troll - but I
> can't help but notice that ets and even Mnesia is recommended before
> process dictionary (which is very heavily frowned upon) in this thread,
> and I am not sure if I understand the reason, unless process dictionary
> is technically inferior or broken. From FP perspective, neither is
> pure, so why one better than another?
> There must be a reason for the level of discouragement about a built-in
It is not a bad question, and I'll try to give some sort of answer.
The main point is that if you think that you need to use the process
dictionary, you are most likely designing your program around (process-)
global variables. This means that your code will contain many more
hidden assumptions than when you are passing around all your parameters
explicitly. It will make it harder to understand, maintain, fix bugs
in, and refactor. In contrast, when only the necessary parameters are
being passed around to functions, it becomes much easier to see patterns
emerge in your code - which groups of functions use a particular
parameter, and which do not. This helps you realize important things
about your code while you are developing it. Even when you group a
bunch of parameters together in a "state" record, the simple fact that
the passing around of the state is visible can help you see which
functions actually need it at all, or use only some specific components
of the state.
The process dictionary is, I find, mainly useful for process-global
options and similar parameters which tend to be orthogonal to the main
functionality of the code. For that sort of thing, it is by definition
difficult to predict in which functions you will suddenly require access
to the value, and to handle it in a functional way you'd be forced to
thread an "options" parameter through all of your calls. So, there are
definitely some cases where it is useful. I suppose that the dire
warnings about using it are mainly due to the fact that if you are
trying to teach old programmers to write good Erlang code, you must give
them a hard slap every time they go near the process dictionary, or they
will start to write Fortran code in Erlang instead of learning good
functional programming patterns.
The use of ets or mnesia is a bit different. In both cases, it is more
or less implied that you use large-ish tables with some sort of uniform
structure or database schema; you wouldn't (well, nobody would expect
you to) create an ets table just to use it as a big old set of global
variables with random contents such as [x -> 42, y -> "hello", ...].
Also, with ets tables at least, you can keep your tables anonymous and
pass the handle around between functions in a visible way, much like
you would do with any functional data structure such as dict. And of
course, the interfaces to ets or mnesia are a bit more heavyweight
than get/put, so it is a little more obvious when reading the code
that there is a table access going on at that point.
The bottom line is that yes, if you have some process-global write-once
parameters, that are more or less orthogonal to the main functionality
of the code, then the process dictionary is a good place to put them.
(Just choose your key names well - if you call out to some other code
which has the same idea and uses the same key, it will overwrite your
value.) The reason for all the discouragement is pedagogical; you don't
want people to start using the process dictionary for problem solving
until they have mastered writing in a functional style.
More information about the erlang-questions