[erlang-questions] Why single-assignment with non-shared state?
Sat Oct 20 15:52:23 CEST 2007
2007/10/20, Matej Kosik <kosik@REDACTED>:
> Doesn't shadowing of meanings of variables in Erlang similarly
> complicate reasoning? (in one position some variable has some
> meaning and elsewhere in the term suddenly has different meaning).
Well, it could, but in most cases where it would be confusing, the
compiler will give you a warning.
Personally, I try to use some naming convention for variables to
minimize the risk of confusion.
> Non-functional features of Erlang are present in its fundamental constructs:
> - - send
> - - receive
> - - spawn
> These cannot be modelled in (purely) functional languages, can they? How?
Almost by definition, the answer is "no", I think? (:
(I guess I should let the real language experts answer this, but it's Saturday,
and I don't have anything better to do right now. I trust I'll get my fingers
slapped if I write something stupid).
At least it's difficult. Haskell uses 'monads', to clearly mark where the code
has side-effects. This allows the compiler to trust that all code outside of
the monad is pure. Other languages can use the fact that these operations
are contained within the runtime, and can optimize them. Felix* does this,
for example; I don't know about Concurrent ML. I believe that when Felix
participated in the Language Shootout, its compiler reduced the concurrency
benchmark down to a function that did nothing**. This doesn't mean that
Felix models "fibres" as being pure, but as long as the effect of the
impurity is understood, a smart compiler can sometimes eliminate it,
or at least simplify it significantly. I guess this is sort of a grey area. (:
It is partly connected to the fact that most of the surroundings are pure,
and very well understood. Erlang can, for example, decide to pass a
pointer rather than copy a message, since there are no user-level
operations that can mess with the low-level representation of the
message. There was once a paper suggesting that a gen_server:call()
could be reduced to a function call, under certain circumstances
(http://www.erlang.se/workshop/2002/Stenman.pdf), but it
suggested dynamic checking to ensure that the conditions were met,
since it would be difficult to do statically in Erlang.
(OHaskell not only performs this check statically, it enforces it:
Erlang's approach is fairly pragmatic. It has basically tried to make sure
that all non-pure operations can be modeled using spawn, send and receive,
but the only parts of an erlang program that the compiler can trust to be
free from side-effects are clause heads, the left hand side of an expression
(pattern matching), and guard expressions. Every (non-guard) function call
can potentially result in a side-effect. Some BIFs are also known to be pure
and can be optimized by the compiler.
* http://www.felix-lang.org - a OCaml/C++ hybrid of sorts
** This Felix entry was disqualified, which caused some debate. Google
will tell you more.
More information about the erlang-questions