[erlang-questions] Why isn't erlang strongly typed?

Richard O'Keefe ok@REDACTED
Thu Oct 23 02:04:47 CEST 2008

There is continuing debate in the programming languages
world about the merits of types.

Consider four kinds of languages.

Dynamic type systems.
  Here we find Lisp, Smalltalk, Erlang, Python, JavaScript, Prolog, &c.
  Systems where variables are not annotated with types at
  compile time, but where the run time type system is not breakable
  by any means in the language.

  "Type errors" do exist as a run-time concept, just like
  division by zero, index out of range, and file won't open.

Feeble type systems.
  Here we find C, Pascal, traditional Fortran, &c.
  Systems where there _is_ a static type system but it is laughably
  easy to bypass it whenever you want to.

  Such a type system has two chief merits:
  - to catch some errors at compile time
  - to let the compiler automatically resolve overloaded
    operator, field, and perhaps function names.

Vanilla type systems.
  Here we find Java and Eiffel and some others.
  Systems where there is a static type system that cannot be
  broken by any means in the language, but some of the checking
  is deferred to run time.

  Type errors remain as a run-time concept, but they are at least
  caught, unlike feeble type systems.

  These type systems provide useful guarantees about types,
  and also allow (some) compile-time resolution of overloaded
  operators (at least in Eiffel), fields, and so on.

  The classical single inheritance model doesn't really work very
  well.  (I've been building a Smalltalk compiler in my spare time
  for a couple of times.  It ran its first method yesterday!  Over
  and over and over I've found single inheritance limiting.)  This
  means either providing multiple inheritance, as in Eiffel, or
  in the limited way offered by the proposed ISO Object-Oriented
  Extensions to Pascal, or in the still more limited interfaces
  of Java, or by divorcing the type hierarchy from the implementation
  hierarchy as in (was it Sather? was it Cecil?).  It also leads,
  early or late, to some sort of parameterised types.

Types as a tool of design.
   Here we find Haskell, Clean, Mercury, arguably SML and CAML,
   and more experimental languages like Agda.

   In these systems the type system is the heart and soul of the
   language.  It's not just a statically unbreakable system with
   no run time type errors, it's not just parameterised types,
   it's types *enhancing* the expressiveness of the language
   rather than limiting it.

   C++ is a weird mixture of feeble (C heritage) + types as a tool
   of design (template metaprogramming).  It doesn't just let you
   shoot yourself in the foot, it gives you an A-bomb factory to
   really do yourself in with.

When "functional" people argue for "typed" languages, they are
generally thinking about types-as-a-tool-of-design.  You can't
just add that to Erlang.  (You can add concurrency to Haskell,
though, which has been done.)  You'd have to overhaul the whole
thing from top to bottom.  That might be a good idea.

So what are the merits of other type systems for Erlang?

Do we want overloaded functions and operators?
Nobody seems to be crying out for them.

Do we have a serious problem with run-time type errors?
Is a type system the only, or the best, way to deal with them?

One aspect of unit testing frameworks is that if you test each
function in a module even a few times, you are going to smoke
out most type errors fairly quickly.  You will also find many
mistakes that a type system will not catch.

A suitable notation, such as Smalltalk/Objective-C split method
names, can prevent most type errors in the first place.

Last year I kept a log of the mistakes I was finding in my
Smalltalk system.  I haven't kept it up this year, because
I'd learned the main thing I wanted to learn: errors that
would have been caught by a type checker and not by other
means were quite rare.

As yet, I don't think any of the languages I know has a type
system that works in a *distributed* system except by taking
a single program built at one time and chopping it up into
distributed pieces (which is how Ada does it).  Clean seems
to be aimed in that direction, but the pieces of the manual
that ought to describe the key ideas are still missing.

Let me give you a recent example of what can go wrong.
Some of my 4th year students wrote a compiler for a parallel
programming language (a stripped down Java + 'in parallel' +
'wait until').  I couldn't run it.  It was type checked and
everything, but for the Java 1.6 libraries, and I had the
1.5 libraries.  Now think of exchanging objects between their
machine and mine...

More information about the erlang-questions mailing list