[erlang-questions] *current* value?

Thomas Lindgren thomasl_erlang@REDACTED
Wed Oct 17 23:35:31 CEST 2007


--- YC <yinso.chen@REDACTED> wrote:

> Hi Vance -
> 
> Thanks for the explanations for the different
> approaches in Erlang - this is
> great.
> 
> 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
> facility.

I'm not as opposed to using the process dictionary,
and don't really see a big difference in principle vs
other forms of state. That said, I don't use it much
in practice. I find "stateless" functions to be easier
to use, reuse and test and the process dictionary API
to be a bit unwieldy. 

In practice, with the process dictionary you tend to
do put/get on what is basically global variables (for
that process), so you get problems with reentrancy and
must ensure that you're not calling the function
improperly. You also have the problem of making up
good names for your global variables (no name clashes
please). And there is no good way to save and restore
a whole process dictionary, which is what you'd need
occasionally. (Well, I see there are at least some
BIFs for reading the whole thing. So I may not be
keeping up with the latest and greatest in that.)

Here is an example where things go wrong: you want to
write a map and store the function to use in the
process dictionary to save passing around F as a
parameter.

map(F, Xs) -> 
  put(map_f, F), Ys = map_pd(Xs), erase(map_f), Ys.

map_pd([]) -> [];
map_pd([X|Xs]) -> F = get(map_f), [F(X)|map_pd(Xs)].

So, you set the variable map_f, use it and even clean
it up afterwards. Great. The problem happens when you
want to do a nested map on a list of lists:

map(fun(Xs) -> map(fun f/1, Xs) end, Xss).

When you call the inner map, map_f is set to fun f/1,
then you return and it is erased. The function is not
reentrant, and to get it right, you would have to save
and restore the old value yourself. (Ghastly.) Or you
have to be careful about how you and everybody else
uses it.

As performance goes, however, I think the process
dictionary is noticeably faster than ets. (Didn't
someone post a fast implementation of some ACM
challenge algorithm using the process dictionary a
couple of months ago?) And apart from setting global
"read-only" variables, I very occasionally also use it
for global counters etc. The random library does too. 

Perhaps one could summarize the process dictionary as
a technology for "programming in the small".

Best,
Thomas


__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 



More information about the erlang-questions mailing list