More lazy values, the State monad and other stateful stuff

In the previous post, we talked about lazy evaluation in Scala. At the end of that post, we asked an interesting question: Does a Lazy value hold an state?

24195622

In order to answer that question, we’ll try to define a type that could represent the Lazy values:

trait Lazy[T] {

  val evalF : () => T

  val value: Option[T] = None

}
object Lazy{
  def apply[T](f: => T): Lazy[T] =
    new Lazy[T]{ val evalF = () => f }
}

As you can see, our Lazy type is parameterized by some T type that represents the actual value type(Lazy[Int] would be the representation for a lazy integer).
Besides that, we can see that it’s composed of the two main Lazy type features:

  • evalF : Zero-parameter function that, when its ‘apply’ method is invoked, it evaluates the contained T expression.
  • value : The result value of the interpretation of the evalF function. This concrete part denotes the state in the Lazy type, and it only admit two possible values: None (not evaluated) or Some(t) (if it has been already evaluated and the result itself).

We’ve also added a companion object that defines the Lazy instance constructor that receives a by-name parameter that is returned as result of the evalF function.

e9a2295b3db9b45c8f5484a09033c1c71cf88e3375bb7ff60456bc81c29a4e04

Now the question is, how do we join both the evaluation function and the value that it returns so we can make Lazy an stateful type? We define the ‘eval’ function this way:

trait Lazy[T] { lzy =>

  val evalF : () => T

  val value: Option[T] = None

  def eval: (T, Lazy[T]) = {
    val evaluated = evalF.apply()
    evaluated -> new Lazy[T]{ mutated =>
      val evalF = lzy.evalF
      override val value = Some(evaluated)
      override def eval: (T, Lazy[T]) = 
        evaluated -> mutated
    }
  } 

}

The ‘eval’ function returns a two-element tuple:

  • The value result of evaluating the expression that stands for the lazy value.
  • a new Lazy value version that contains the new state: the T evaluation result.

If you take a closer look, what ‘eval’ method does in first place is to invoke the evalF function so it can retrieved the T value that remained until that point not-evaluated.
Once done, we return it as well as the new Lazy value version. This new version (let’s call it mutated version) will have in its ‘value’ attribute the result of having invoked the evalF function. In the same way, we change its eval method, so in future invocations the Lazy instance itself is returned instead of creating new instances (because it actually won’t change its state, like Scala’s lazy definitions work).

The interesting question that comes next is: is this an isolated case? Could anything else be defined as stateful? Let’s perform an abstraction exercise.

Looking for generics: stateful stuff

Let’s think about a simple stack:

sealed trait Stack[+T]
case object Empty extends Stack[Nothing]
case class NonEmpty[T](head: T, tail: Stack[T]) extends Stack

The implementation is really simple. But let’s focus in the Stack trait and in a hypothetical pop method that pops an element from the stack so it is returned as well as the rest of the stack:

sealed trait Stack[+T]{
  def pop(): (Option[T], Stack[T])
}

Does it sound familiar to you? It is mysteriously similar to

trait Lazy[T]{
  def eval: (T, Lazy[T])
}

isn’t it?

If we try to re-factor for getting a common trait between Lazy and Stack, we could define a much more abstract type called State:

trait State[S,T] {
  def apply(s: S): (T, S)
}

Simple but pretty: the State trait is parameterized by two types: S (state type) and T (info or additional element that is returned in the specified state mutation). Though it’s simple, it’s also a ver common pattern when designing Scala systems. There’s always something that holds certain state. And everything that has an state, it mutates. And if something mutates in a fancy and smart way…oh man.

That already exists…

24314442

All this story that seems to be created from a post-modern essay, has already been subject of study for people…that study stuff. Without going into greater detail, in ScalaZ library you can find the State monad that, apart from what was previously pointed, is fully-equipped with composability and everything that being a monad means (semigroup, monoid, …).

If we define our Lazy type with the State monad, we’ll get something similar to:

import scalaz.State

type Lazy[T] = (() => T, Option[T])

def Lazy[T](f: => T) = (() => f, None)

def eval[T] = State[Lazy[T], T]{
  case ((f, None)) => {
    val evaluated = f.apply()
    ((f, Some(evaluated)), evaluated)
  }
  case s@((_, Some(evaluated))) => (s, evaluated) 
}

When decrypting the egyptian hieroglyph, given the State[S,T] monad, we have that our S state will be a tuple composed of what exactly represents a lazy expression (that we also previously described):

type Lazy[T] = (() => T, Option[T])
  • A Function0 that represents the lazy evaluation of T
  • The T value that might have been evaluated or not

For building a Lazy value, we generate a tuple with a function that stands for the expression pointed with the by-name parameter of the Lazy method; and the None value (because the Lazy guy hasn’t been evaluated yet):

def Lazy[T](f: => T) = (() => f, None)

Last, but not least (it’s actually the most important part), we define the only state transition that is possible in this type: the evaluation. This is the key when designing any State type builder: how to model what out S type stands for and the possible state transitions that we might consider.

In the case of the Lazy type, we have two possible situations: the expression hasn’t been evaluated yet (in that case, we’ll evaluate it and we’ll return the same function and the result) or the expression has been already evaluated (in that case we won’t change the state at all and we’ll return the evaluation result):

def eval[T] = State[Lazy[T], T]{
  case ((f, None)) => {
    val evaluated = f.apply()
    ((f, Some(evaluated)), evaluated)
  }
  case s@((_, Some(evaluated))) => (s, evaluated) 
}

iZcUNxH

In order to check that we can still count on the initial features we described for the Lazy type (it can only be evaluated once, only when necessary, …) we check the following assertions:

var sideEffectDetector: Int = 0

val two = Lazy {
  sideEffectDetector += 1
  2
}

require(sideEffectDetector==0)

val (_, (evaluated, evaluated2)) = (for {
  evaluated <- eval[Int]
  evaluated2 <- eval[Int]
} yield (evaluated, evaluated2)).apply(two)

require(sideEffectDetector == 1)
require(evaluated == 2)
require(evaluated2 == 2)

Please, do notice that, as we mentioned before, what is defined inside the for-comprehension are the same transitions or steps that the state we decide will face. That means that we define the mutations that any S state will suffer. Once the recipe is defined, we apply it to the initial state we want.
In this particular case, we define as initial state a lazy integer that will hold the 2 value. For checking the amount of times that our Lazy guy is evaluated, we just add a very dummy var that will be used as a counter. After that, we define inside our recipe that the state must mutate twice by ussing the eval operation. Afterwards we’ll check that the expression of the Lazy block has only been evaluated once and that the returning value is the expected one.

I wish you the best tea for digesting all this crazy story 🙂
Please, feel free to add comments/menaces at the end of this post or even at our gitter channel.

See you on next post.
Peace out!

Más lazy’s, la mónada State y otras cosas con estado

En el anterior post hablábamos sobre la evaluación perezosa en Scala. Al final de dicho post, planteábamos una pregunta: ¿Un Lazy tiene estado?

24195622

Para responder a dicha pregunta, vamos a intentar definir un tipo que represente un valor Lazy como sigue:

trait Lazy[T] {

  val evalF : () => T

  val value: Option[T] = None

}
object Lazy{
  def apply[T](f: => T): Lazy[T] =
    new Lazy[T]{ val evalF = () => f }
}

Como se puede observar, nuestro tipo Lazy está parametrizado por un tipo T que representa el tipo del valor en cuestión(Lazy[Int] sería la representación de un entero perezoso).
Además, podemos ver que se compone de dos elementos principales que caracterizan a un Lazy:

  • evalF : Función de cero argumentos que, al invocar su método apply, evalúa la expresión de T contenida.
  • value : El valor resultante de la interpretación de la función evalF. Esta parte es la que denota el estado en el tipo Lazy, y solo admite dos posibles valores: None (no evaluado) o Some(t) (si ya ha sido evaluado y el resultado obtenido).

También hemos añadido un objeto companion que define el constructor de instancias Lazy que recibe un argumento by-name que se devuelve como resultado de la función evalF.

e9a2295b3db9b45c8f5484a09033c1c71cf88e3375bb7ff60456bc81c29a4e04

La cuestión ahora es: ¿Cómo unimos la función de evaluación con el valor que devuelve para hacer que Lazy mantenga un estado? Definiendo la función eval:

trait Lazy[T] { lzy =>

  val evalF : () => T

  val value: Option[T] = None

  def eval: (T, Lazy[T]) = {
    val evaluated = evalF.apply()
    evaluated -> new Lazy[T]{ mutated =>
      val evalF = lzy.evalF
      override val value = Some(evaluated)
      override def eval: (T, Lazy[T]) = 
        evaluated -> mutated
    }
  } 

}

La función eval devuelve una tupla de dos elementos:

  • el valor resultante de la evaluación de la expresión que representa el valor perezoso.
  • una nueva versión del valor Lazy que contiene el nuevo estado: el resultado de la evaluación.

Si os fijáis, lo que hace el método en primer lugar, es invocar a la función evalF para obtener el valor de tipo T que aún estaba sin evaluar.
Una vez hecho esto, lo devolvemos así como la nueva versión del elemento Lazy. Esta nueva versión (llamémosla mutated) tendrá en su atributo value el resultado de haber invocado a evalF. Del mismo modo, modificamos su método eval, para que en sucesivas invocaciones se devuelva a sí mismo y no genere nueva instancias que en realidad no varían su estado.

La cuestión interesante viene ahora: ¿es este un caso único? ¿Existen más ‘cosas’ que mantienen un estado? Hagamos un ejercicio de abstracción.

Buscando la genericidad: cosas-con-estado

Pensemos en el caso de una pila:

sealed trait Stack[+T]
case object Empty extends Stack[Nothing]
case class NonEmpty[T](head: T, tail: Stack[T]) extends Stack

La implementación sale casi sola. Pero centrémonos en el trait Stack y en un hipotético método pop que desapila un elemento que se devuelve junto al resto de la pila:

sealed trait Stack[+T]{
  def pop(): (Option[T], Stack[T])
}

¿Os suena de algo? ¿No se parece misteriosamente a

trait Lazy[T]{
  def eval: (T, Lazy[T])
}

…?

Si intentamos sacar factor común entre Lazy y Stack podríamos definir un tipo mucho más abstracto llamado State:

trait State[S,T] {
  def apply(s: S): (T, S)
}

Simple pero bello: el trait State está parametrizado por dos tipos: S (tipo de estado) y T (información o elemento adicional que devuelve cada vez que mutamos el estado). Aquí donde lo veis, se trata de un patrón muy recurrente al diseñar sistemas en Scala. Siempre hay algo que mantiene un estado. Y todo lo que tiene estado muta. Y si ese algo muta de manera segura y elegante…oh man.

Esto ya existe …

21495586

Toda esta historia que parece sacada de un ensayo post-moderno, resulta que ya ha sido objeto de estudio de personas que estudian cosas. Sin entrar en mucho detalle, en la librería ScalaZ podéis encontrar la mónada State que, además de lo descrito anteriormente, trae de serie un full-equipped de componibilidad y todo lo que conlleva ser Mónada (semigrupo, monoide, etc).

Si definimos nuestro tipo Lazy con la mónada State tenemos algo como:

import scalaz.State

type Lazy[T] = (() => T, Option[T])

def Lazy[T](f: => T) = (() => f, None)

def eval[T] = State[Lazy[T], T]{
  case ((f, None)) => {
    val evaluated = f.apply()
    ((f, Some(evaluated)), evaluated)
  }
  case s@((_, Some(evaluated))) => (s, evaluated) 
}

Al descomponer el jeroglífico egipcio arriba expuesto, dada la mónada State[S,T], nuestro estado S va a ser una tupla de lo que representa en el fondo a una evaluación perezosa:

type Lazy[T] = (() => T, Option[T])

y que más arriba hemos descrito:

  • Una Function0 que representa la evaluación demorada de T
  • El valor T que puede haberse evaluado o no

Para construir un valor Lazy, generamos una tupla con una función que recoge la expresión indicada por un argumento by-name del método Lazy y el valor None (porque aún no ha sido evaluado el Lazy):

def Lazy[T](f: => T) = (() => f, None)

Por último (y esta es la parte importante) definimos la única transición posible de estado que podemos concebir cuando hablamos de valores perezosos: la evaluación. Esta es la clave cuando diseñamos cualquier constructor de tipos que extiende de State: lo importante es modelar qué es nuestro tipo S y las transiciones de estado posibles.

Para el tipo Lazy, tenemos dos posibles casos: que la expresión aún no haya sido evaluada (en cuyo caso la evaluamos y devolvemos la misma función y el resultado) ó que la expresión ya haya sido evaluada (en cuyo caso dejamos el estado como está y devolvemos además el resultado de la evaluación):

def eval[T] = State[Lazy[T], T]{
  case ((f, None)) => {
    val evaluated = f.apply()
    ((f, Some(evaluated)), evaluated)
  }
  case s@((_, Some(evaluated))) => (s, evaluated) 
}

iZcUNxH

Para comprobar que seguimos contando con las mismas características iniciales para las que definimos el tipo Lazy (solo se evalúa una vez, solo se evalúa cuando es necesario, …) lanzamos las siguiente aserciones:

var sideEffectDetector: Int = 0

val two = Lazy {
  sideEffectDetector += 1
  2
}

require(sideEffectDetector==0)

val (_, (evaluated, evaluated2)) = (for {
  evaluated <- eval[Int]
  evaluated2 <- eval[Int]
} yield (evaluated, evaluated2)).apply(two)

require(sideEffectDetector == 1)
require(evaluated == 2)
require(evaluated2 == 2)

Si os fijáis, como antes comentábamos, lo que se define en la for-comprehension son las transiciones o pasos que va a enfrentar el estado que nosotros queramos. Es decir, definimos las mutaciones que sufrirá un estado S cualquiera. Una vez definida la ‘receta’, la aplicamos al estado inicial que nosotros queramos.
En este caso, definimos como estado inicial un perezoso número entero dos. Para comprobar el número de veces que se evalúa nuestro Lazy, añadimos un var muy dummy que funcionará a modo de contador. Luego definimos en nuestra ‘receta’ que el estado debe mutar dos veces mediante la operación eval. Posteriormente comprobamos que solo se ha ejecutado una vez la expresión del bloque Lazy y que el valor resultante de la expresión es el esperado.

Os deseo la mejor de las sales de frutas para digerir todo esto 🙂
Sentíos libres de añadir comentarios/amenazas en el post o en nuestro canal de gitter.

Hasta el próximo post.
¡Agur de limón!

Scalera tip: Why ‘scala.util.Try’ doesn’t have ‘finally’ clause?

Some days ago, a work colleage raised the million-dollar question.

If we use the traditional java try, we could be handling some code similar to this:

val connection = database.getConnection()
var data: Seq[Data] = Seq()
try {
  val results = connection.query("select whatever")
  data = results.map(convertToWhatIneed)
} catch {
  case t: Throwable => logger.error("Oh noes!")
} finally {
  connection.close()
}

In Scala, we have a more functional version of this mechanism: scala.util.Try.
The same example could be implemented by using this data type:

val connection = database.getConnection()
val data: Seq[Data] = Try{
  val results = connection.query("select whatever")
  val data: Seq[Data] = 
    results.map(convertToWhatIneed)
  connection.close()
  data
} recover {
  case t: Throwable => 
    logger.error("Oh noes!")
    connection.close()
    Seq.empty[Data]
} get

The question is, why doesn’t scala.util.Try even consider a finally clause like Java’s try?

Side effects….side effects everywhere…

If you remember the post where David talked about Try[T] data type, it’s a type that may have two different possible values Success(t: T) or Failure(t: Throwable).

On the other hand, if you remembet another post where we talked about vals and vars, we mentioned the referential transparency as principle that must be followed for considering a function to be pure.

So, if we test this principle with the previously described snippet, we could replace the Try[Seq[Data]] expression with the same type value that we would have got by evaluating the expression; and we should retrieve the same result. I.e.:

val connection = database.getConnection()
val data: Seq[Data] = 
  Success(Seq(data1,data2,data3)).get

We can see it hasn’t closed the connection that we opened before though…

o6dau

For this reason, it makes more sense to code something like this:

val connection = database.getConnection()
val data: Seq[Data] = Try{
  val results = connection.query("select whatever")
  results.map(convertToWhatIneed)
} recover {
  case t: Throwable => 
    Seq.empty[Data]
} get
connection.close()

This way, the data value can be replaced easily, without any extra side effect implication.

…And for this reason, fellows, it doesn’t make sense to think about a finally clause for Try[T]! 🙂

Peace out!

Scalera tip: ¿Por qué ‘scala.util.Try’ no tiene ‘finally’?

Hace algunos días, un compañero del trabajo planteó la duda del millón.

Si usamos el try tradicional de Java, podríamos encontrarnos con código similar a:

val connection = database.getConnection()
var data: Seq[Data] = Seq()
try {
  val results = connection.query("select whatever")
  data = results.map(convertToWhatIneed)
} catch {
  case t: Throwable => logger.error("Oh noes!")
} finally {
  connection.close()
}

En Scala, disponemos de una versión más funcional de este mecanismo: scala.util.Try.
El mismo ejemplo, utilizando esté tipo de datos, sería algo como

val connection = database.getConnection()
val data: Seq[Data] = Try{
  val results = connection.query("select whatever")
  val data: Seq[Data] = 
    results.map(convertToWhatIneed)
  connection.close()
  data
} recover {
  case t: Throwable => 
    logger.error("Oh noes!")
    connection.close()
    Seq.empty[Data]
} get

La pregunta es, ¿por qué scala.util.Try no considera una claúsula finally como el try de java?

Side effects….side effects everywhere…

Si recordáis el post en el que David habló sobre el tipo Try[T], es un tipo que puede tener dos posibles estados: Success(t: T) o Failure(t: Throwable).

Por otra parte, si hacéis memoria sobre el post en el que hablábamos sobre los valores y las variables, mencionábamos la transparencia referencial como principio que debe cumplirse para considerar una función pura.

Por lo tanto, si ponemos a prueba este principio con el snippet arriba descrito, podríamos sustituir la expresión de tipo Try[Seq[Data]] por el valor del mismo tipo que hubiéramos obtenido al evaluar la expresión, y deberíamos tener el mismo resultado. Por ejemplo:

val connection = database.getConnection()
val data: Seq[Data] = 
  Success(Seq(data1,data2,data3)).get

Sin embargo, vemos que no ha cerrado la conexión que hemos abierto justo antes…

o6dau

Por ese motivo, tiene más lógica hacer algo así como:

val connection = database.getConnection()
val data: Seq[Data] = Try{
  val results = connection.query("select whatever")
  results.map(convertToWhatIneed)
} recover {
  case t: Throwable => 
    Seq.empty[Data]
} get
connection.close()

De esta forma, el valor de data puede ser sustituido fácilmente, sin implicar más efectos de lado.

…¡y por esto, amigos, no tiene sentido pensar en un finally para Try[T]! 🙂

Agur de limón

Scalera tips: How NOT to change your actor’s state

A common key when working with Akka, is modifying properly our actor’s state. If we jog our memory, this framework paradigm allows us to program modeling the concurrency based on actors and message passing. From that base, we could define an actor as a computing unit that may have state and perform tasks based on messages that it will receive through its mailbox and that will be processed sequentially .

That means that, in order to avoid side effects, the actor’s state modification has to take place when processing a message. So senseful so far. However, it’s a pretty common mistake to do something similar to this:

class MyActor extends Actor {

  var state: Int = 0

  def receive = {

    case "command" => 
      Future(state = 1)

    case "someOtherCommand" => 
      state = 2

  }

}

In this case, we have no more warranty that the state change (whose only responsible of keeping it consistent and thread safe is the actor) might cause side efects given that, in the precise moment where the Future modifies the var, it’s possible that the state is being modified by the actor itself (probably as a reaction to some other received message).

This Future[Unit] might not be a block like that. It could be the result of having asked to some other actor:

class MyActor extends Actor {

  type State = Int

  var state: State = 0

  def receive = {

    case "command" => 
      (service ? "giveMeMyNewState").map{
        case newState: State => state = newState
      }

    case "someOtherCommand" => 
      state = 2
  }

}

Something that probably none of us has ever tried.

giphy

The proper way

If we want to modify the actor’s state as result of having previously asked to some other actor and without breaking the concurrency control of the actor, it could be achieved like this:

class MyActor extends Actor {

  type State = Int

  var state: State = 0

  def receive = {

    case "command" => 
      (service ? "giveMeMyNewState") pipeTo self

    case "someOtherCommand" => 
      state = 2

    case newState: State => 
      state = newState
  }

}

With pipeTo we specify to send to certain actor the result of having evaluated some future when its resolved. This way we’re indicating that, when we get the response of the other actor, it will be sent to our mailbox, so it will be processed like a normal message, sequentially.

bill_murray_gif_1

Easy peasy 🙂

Scalera tips: Como NO modificar el estado de tu actor

Una cuestión habitual a la hora de trabajar con Akka, es modificar de manera correcta el estado de nuestro actor. Si recordamos la base del paradigma de este framework que nos permite programar modelando la concurrencia en base a actores y el paso de mensajes, es que un actor puede definirse como una unidad computacional que puede tener estado y realiza tareas en base a mensajes que recibe en su mailbox y que procesará de manera secuencial.

Esto significa que, para no tener efectos de lado, es necesario que la modificación del estado del actor se haga al procesar un mensaje. Hasta aquí todo tiene sentido. No obstante, es un fallo bastante común el hacer algo del siguiente estilo:

class MyActor extends Actor {

  var state: Int = 0

  def receive = {

    case "command" => 
      Future(state = 1)

    case "someOtherCommand" => 
      state = 2

  }

}

En ese caso, ya no tenemos garantía de que el cambio de estado (cuyo único responsable de mantenerlo consistente y thread-safe es el actor) puede generar efectos de lado dado que en el momento en que futuro modifica el var es posible que el estado esté siendo modificado por el propio actor, desencadenado por el procesamiento de otro mensaje.

Este Future[Unit] puede no ser un bloque como tal, sino el resultado de haber preguntado a otro actor:

class MyActor extends Actor {

  type State = Int

  var state: State = 0

  def receive = {

    case "command" => 
      (service ? "giveMeMyNewState").map{
        case newState: State => state = newState
      }

    case "someOtherCommand" => 
      state = 2
  }

}

Algo que probablemente nadie de nosotros haya intentado jamás.

giphy

La forma correcta

En caso de querer modificar el estado del actor como resultado de dicha consulta a otro actor sin romper el control de concurrencia sobre el estado, se podría hacer como sigue:

class MyActor extends Actor {

  type State = Int

  var state: State = 0

  def receive = {

    case "command" => 
      (service ? "giveMeMyNewState") pipeTo self

    case "someOtherCommand" => 
      state = 2

    case newState: State => 
      state = newState
  }

}

Con pipeTo lo que hacemos es mandar a cierto actor el resultado de evaluar un futuro cuando este se resuelva. De esta manera estamos indicando que, cuando tengamos la respuesta del otro actor, se envie a nuestro mailbox, de manera que se procesará como otro mensaje más, de manera secuencial.

bill_murray_gif_1

Easy peasy 🙂