Antes que nada, creo que es importante definir la diferencia entre concurrencia y paralelismo. En muchos lugares, ambas palabras se refieren al mismo concepto. A menudo se usan como dos ideas diferentes en el contexto de Erlang. Para muchos erlangeros, la concurrencia se refiere a la idea de tener muchos actores ejecutándose de forma independiente, pero no necesariamente todos al mismo tiempo. El paralelismo es tener actores ejecutándose exactamente al mismo tiempo. Diré que no parece haber ningún consenso sobre tales definiciones en varias áreas de la informática, pero las usaré de esta manera en este texto. No se sorprenda si otras fuentes o personas usan los mismos términos para referirse a cosas diferentes.
Esto quiere decir que Erlang tenía concurrencia desde el principio, incluso cuando todo se hacía en un procesador de un solo núcleo en los años 80. Cada proceso de Erlang tenía su propio tiempo para ejecutarse, de forma muy similar a las aplicaciones de escritorio antes de los sistemas multinúcleo.
El paralelismo todavía era posible en ese entonces; todo lo que se necesitaba hacer era tener una segunda computadora ejecutando el código y comunicándose con la primera. Incluso entonces, solo se podían ejecutar dos actores en paralelo en esta configuración. Hoy en día, los sistemas multinúcleo permiten el paralelismo en una sola computadora (algunos chips industriales tienen muchas docenas de núcleos) y Erlang aprovecha al máximo esta posibilidad.
La distinción entre concurrencia y paralelismo es importante, porque muchos programadores creen que Erlang estaba listo para las computadoras multinúcleo años antes de que realmente lo estuviera. Erlang se adaptó al multiprocesamiento simétrico verdadero recién a mediados de la década de 2000 y recién logró implementar la mayor parte de la información correctamente con la versión R13B del lenguaje en 2009. Antes de eso, a menudo era necesario deshabilitar SMP para evitar pérdidas de rendimiento. Para obtener paralelismo en una computadora multinúcleo sin SMP, se debían iniciar muchas instancias de la máquina virtual.
Un hecho interesante es que, debido a que la concurrencia de Erlang se basa en procesos aislados, no fue necesario ningún cambio conceptual a nivel de lenguaje para lograr un paralelismo verdadero en el lenguaje. Todos los cambios se realizaron de manera transparente en la máquina virtual, fuera de la vista de los programadores.