Permítanme decir primero que tengo mucha experiencia en Java, pero solo recientemente me he interesado en los lenguajes funcionales. Recientemente comencé a buscar en Scala, que parece un lenguaje muy agradable.
Sin embargo, he estado leyendo sobre el marco Actor de Scala en Programación en Scala , y hay una cosa que no entiendo. En el capítulo 30.4 dice que usar en react
lugar de receive
permite reutilizar subprocesos, lo cual es bueno para el rendimiento, ya que los subprocesos son costosos en la JVM.
¿Significa esto que, siempre que me acuerde de llamar en react
lugar de receive
, puedo iniciar tantos Actores como quiera? Antes de descubrir Scala, he estado jugando con Erlang, y el autor de Programming Erlang se jacta de generar más de 200.000 procesos sin sudar. Odiaría hacer eso con los hilos de Java. ¿Qué tipo de límites estoy mirando en Scala en comparación con Erlang (y Java)?
Además, ¿cómo funciona la reutilización de este hilo en Scala? Supongamos, por simplicidad, que solo tengo un hilo. ¿Todos los actores que empiezo se ejecutarán secuencialmente en este hilo, o se producirá algún tipo de cambio de tarea? Por ejemplo, si comienzo a dos actores que se envían mensajes de ping-pong entre sí, ¿correré el riesgo de un punto muerto si comienzan en el mismo hilo?
Según Programming in Scala , escribir actores para usar react
es más difícil que con receive
. Esto suena plausible, ya react
que no regresa. Sin embargo, el libro continúa mostrando cómo se puede poner react
dentro de un bucle usando Actor.loop
. Como resultado, obtienes
loop {
react {
...
}
}
que, para mí, parece bastante similar a
while (true) {
receive {
...
}
}
que se utiliza anteriormente en el libro. Aún así, el libro dice que "en la práctica, los programas necesitarán al menos algunos receive
". Entonces, ¿qué me estoy perdiendo aquí? ¿Qué puede receive
hacer que react
no pueda, además de regresar? ¿Y por qué me importa?
Finalmente, llegando al núcleo de lo que no entiendo: el libro sigue mencionando cómo el uso react
hace posible descartar la pila de llamadas para reutilizar el hilo. ¿Cómo funciona? ¿Por qué es necesario descartar la pila de llamadas? ¿Y por qué se puede descartar la pila de llamadas cuando una función termina lanzando una excepción ( react
), pero no cuando termina devolviendo ( receive
)?
Tengo la impresión de que Programming in Scala ha pasado por alto algunos de los problemas clave aquí, lo cual es una pena, porque de lo contrario es un libro realmente excelente.