(No conozco a Erlang, y no puedo escribir Haskell, pero creo que puedo responder)
Bueno, en esa entrevista se da el ejemplo de una biblioteca de generación de números aleatorios. Aquí hay una posible interfaz con estado:
# create a new RNG
var rng = RNG(seed)
# every time we call the next(ceil) method, we get a new random number
print rng.next(10)
print rng.next(10)
print rng.next(10)
La salida puede ser 5 2 7
. Para alguien a quien le gusta la inmutabilidad, ¡esto es simplemente incorrecto! Debería serlo 5 5 5
, porque llamamos al método en el mismo objeto.
Entonces, ¿cuál sería una interfaz sin estado? Podemos ver la secuencia de números aleatorios como una lista vagamente evaluada, donde next
realmente recupera la cabeza:
let rng = RNG(seed)
let n : rng = rng in
print n
let n : rng = rng in
print n
let n : rng in
print n
Con dicha interfaz, siempre podemos volver a un estado anterior. Si dos partes de su código se refieren al mismo RNG, en realidad obtendrán la misma secuencia de números. En una mentalidad funcional, esto es altamente deseable.
Implementar esto en un lenguaje con estado no es tan complicado. Por ejemplo:
import scala.util.Random
import scala.collection.immutable.LinearSeq
class StatelessRNG (private val statefulRNG: Random, bound: Int) extends LinearSeq[Int] {
private lazy val next = (statefulRNG.nextInt(bound), new StatelessRNG(statefulRNG, bound))
// the rest is just there to satisfy the LinearSeq trait
override def head = next._1
override def tail = next._2
override def isEmpty = false
override def apply(i: Int): Int = throw new UnsupportedOperationException()
override def length = throw new UnsupportedOperationException()
}
// print out three nums
val rng = new StatelessRNG(new Random(), 10)
rng.take(3) foreach (n => println(n))
Una vez que agrega un poco de azúcar sintáctica para que parezca una lista, en realidad es bastante agradable.