I've known and loved Haskell for more than a decade so when I was "encouraged" to learn Erlang it expected to hate it. I was thoroughly surprised to see how nice it is. As for the syntax, I mostly find it great (but obviously different).
Something I find worth emphasizing: There is exactly one integer type and integers are unbounded. Very few languages gets this right and it's IMO one of the worst mistakes in Haskell. This takes care of a whole slew of bugs and security pitfalls.
I'm still an Erlang n00b, but the lack of a native string type seems a major weakness -- strings are isomorphic to a list of small integers, worse than even Haskell. Please give us something based on Ropes, like in Cedar (http://onlinelibrary.wiley.com/doi/10.1002/spe.4380251203/ab...).
EDIT: typo.
Haskeller here too. We rely on it [Erlang] for a mission-critical program that runs in an embedded linux environment; we use every touted feature of Erlang/OTP too. While I do miss typeclasses, applicatives, strong and static typing, the Reader monad, lens, Attoparsec, and many other wonderful Haskell experiences -- I can safely say that there is currently no mature and cohesive analog of Erlang's best features in Haskell.
- Easy cross-compilation.
- Out-of-the-box distributed RPC and inter-node connections. Extremely important for our product.
- Supervisor trees (the bees-knees of Erlang).
- Isolation of specific functionality into OTP applications with their own supervision hierarchies (some bound to specific "events", like an AMQP Client coming up upon successful WiFi AP association) - this also protects us from the dreaded "xyz had a bug in it and took down the whole program, it's now bricked".
- Hot code loading and release management. This one is particularly awesome. The node itself is told to upgrade via AMQP, it fetches the latest Release, unpacks it, and rebuilds the engine while driving. There are quite a few built-in safe-guards and checks too until you reach the point of no return in the upgrade. Release management is amazing in Erlang, I have yet to see anything like this in any of the languages I've ever used.
- A proliferation of distributed consensus libraries and utilities thanks to Basho. We use plumtree for replicating the state of each node across its cluster within the user's home. Lots of cool features are possible because of this simple but extremely difficult to get right software.
- The dialyzer isn't anywhere near Haskell's type system but it does give us some useful information and checks.
Even though the integer type is unbounded, in practice the vast majority of runtime values are small, thus we can implement them efficiently using tagged pointers [small values are completely contained in the pointer]. LISP and Smalltalk have been doing this since the 70'es. Sun SPARC even _had_ hardware support for doing it with no (zero) overhead, see tagged instructions (https://en.wikipedia.org/wiki/SPARC). Even on x86, it's not that bad; the overhead for the general case is two tag extractions and three predicable (not-taken) branches (we must check for overflow), about five additional instructions. Not zero, but the dynamic frequency of these is much lower in a high-level language than in, say, C.
The performance differences between Erlang and Haskell (etc) are due to many reasons, but primarily due to Erlang being a dynamic PL, with late binding and dynamic typing. This makes efficient implementation hard (heroic efforts on JavaScript not withstanding), but Erlang makes no excuses as its strengths lies elsewhere. If you need fast compute you should do it in C and interface it with Erlang (lots of ways to do that).
I can't speak for Erlang's internals, but Lisp is one of if not the earliest implementer of this concept.
It internally separates the integer space into "fixnums" and "bignums". Fixnums are around register-width and use the plain ol' machine math instructions. Operations which are inferred or declared to stay within fixnum range don't even have bignum calls compiled into them.
Something I find worth emphasizing: There is exactly one integer type and integers are unbounded. Very few languages gets this right and it's IMO one of the worst mistakes in Haskell. This takes care of a whole slew of bugs and security pitfalls.
I'm still an Erlang n00b, but the lack of a native string type seems a major weakness -- strings are isomorphic to a list of small integers, worse than even Haskell. Please give us something based on Ropes, like in Cedar (http://onlinelibrary.wiley.com/doi/10.1002/spe.4380251203/ab...). EDIT: typo.