To my understanding, a major reason that Erlang was written was because they needed a concurrent system with soft real-time guarantees - in order to work for telephony, it had to operate within predictable, bounded amounts of time.
Conventional Prolog wasn't an option* , because the backtracking inherent in its execution model leads to significant variance for worst-case timing for individual operations. The same problem can happen with lazy evaluation, for both time and space - while the sophisticated compiler optimizations can allow for some really remarkable amortized performance, individual worst-case measurements can still have some serious outliers.
* Though Erlang was prototyped in SICStus Prolog.
With lazy evaluation, forcing a thunk for a seemingly minor operation can trigger a burst of postponed work. This can be a problem if it means a sudden drop in a game's framerate, for example, much like non-incremental garbage collectors' pauses have made people wary of using GC. Similarly, a JITting compiler can do more elaborate optimizations if it can afford to stall the program perceptibly while performing them, but that would disqualify the compiler for many real-world uses.
Real-time operation can impact performance, much like implementing full transactions slows down databases. Still, it's a fairly significant feature in its own right, and a language that does concurrency faster overall, but cannot prevent occasional erratic timing, is aiming for a different target than those (e.g. Erlang) that have such guarantees. It's not unusual for a program that juggles tens of thousands of connections to need to respond to them promptly, for example. Concurrency isn't just about performance.
(Also, that's why the Erlang movie has that "Declarative real-time programming NOW!" banner in the background. :) )
Conventional Prolog wasn't an option* , because the backtracking inherent in its execution model leads to significant variance for worst-case timing for individual operations. The same problem can happen with lazy evaluation, for both time and space - while the sophisticated compiler optimizations can allow for some really remarkable amortized performance, individual worst-case measurements can still have some serious outliers.
* Though Erlang was prototyped in SICStus Prolog.
With lazy evaluation, forcing a thunk for a seemingly minor operation can trigger a burst of postponed work. This can be a problem if it means a sudden drop in a game's framerate, for example, much like non-incremental garbage collectors' pauses have made people wary of using GC. Similarly, a JITting compiler can do more elaborate optimizations if it can afford to stall the program perceptibly while performing them, but that would disqualify the compiler for many real-world uses.
Real-time operation can impact performance, much like implementing full transactions slows down databases. Still, it's a fairly significant feature in its own right, and a language that does concurrency faster overall, but cannot prevent occasional erratic timing, is aiming for a different target than those (e.g. Erlang) that have such guarantees. It's not unusual for a program that juggles tens of thousands of connections to need to respond to them promptly, for example. Concurrency isn't just about performance.
(Also, that's why the Erlang movie has that "Declarative real-time programming NOW!" banner in the background. :) )