Constructive criticism of Erlang

Thomas Lindgren <>
Wed Feb 7 11:45:31 CET 2001


I got on a roll here :-)

 wrote:
> I understand this makes the compiler more complex though, but even under
> the current system, more BIFs should be allowed in guards.  I don't see
> why I can't say "when element(N, T) == 0", for example; that's fairly
> lightweight, no?

Guards should basically be side-effect free and guaranteed to
terminate. Note that element/2 is permitted in guards (see p.29 of the
Erlang book).

> 3. Speaking of making the compiler complex, it would be great if it
> could deduce the legal set of types used by each argument in each
> function (perhaps using supplied predicate guards such as record/2), and
> complain at compile-time if it is ever violated in a subsequent function
> call.  I believe this would be the simplest way to apply "strong typing"
> to Erlang (since it doesn't change any existing semantics of the
> language (except for those semantics that are already illegal anyway!))
> There's no way it could catch all type errors (send, fun, etc.) but it
> would be a great step in that direction.

Unfortunately, type checking of function calls can be difficult in
general. For example, hot code loading means remote calls (between
modules) do not have a statically known type. Take the following
definition:

f(X) -> m:g(X).

Since m can be loaded at runtime, you can't say anything about what
type X is expected to be. (In fact, it can change as new versions of m
are loaded.) So you can't statically derive a type for f/1.

There are a number of other problems as well. For example, what _is_ a
'type' in Erlang? In ordinary Hindley-Milner type inference, type
constructors can't overlap: you thus know that F(x1,...,xn) always
belongs to type T. But Erlang programs are not structured that way;
for example, should we separate a tuple {data,X1,X2} from a tuple
{A1,A2,A3} (where A1 could happen to be the atom 'data')? And there are
some other problems as well.

Despite my being a wet blanket above, there has been some work on type
checking Erlang. Joe Armstrong and Thomas Arts worked on it at CSLab,
as did Wadler and Marlow. Ander Lindgren did a Masters on
it. Sven-Olof Nyström has had a stab more recently (I've even tested
his code a bit :-). 

(Thomas Arts now works on verification of Erlang, which may be a more
fruitful track, since it attacks the truly hair-tearingly difficult
bugs.)


Anyway, your message inspired me to look for more dark corners to be
swept. Here are two:

1. I think records should be cleaned up. The underlying
tuple-representation shines through too brightly, and the current
operations are too weak (e.g., switching on record type is
awkward). Not to mention that include-files are required. To be fair,
a better definition is a bit tricky with hot code loading. (There are
a couple of proposals being discussed; one by Richard O'Keefe seems to
be the favorite.)

2. Another vast and poorly lit area is that of exceptions. Today,
there is seldom any way of knowing what sorts of exceptions a function
can throw, and the exceptions are usually uninformative (e.g.,
"badmatch" when you have half a dozen pattern matches in the indicated
function). Thus, _using_ the exit reason to recover from an error is
difficult. In practice, you print, log or ignore an exit today.

I think we should take better advantage of exceptions than we do
today.

> Is there any example code for a Parse Transformation?  (I imagine
> not, since it's discouraged.)

I think Mnemosyne uses parse transforms.

		       Thomas
-- 
Thomas Lindgren					
Alteon WebSystems



More information about the erlang-questions mailing list