Lazy values

Just in case you lived in a hole for the last ten years and you didn’t know: Scala allows managing lazy values.

image

In Scala, we can define a value that won’t be evaluated until it is explicitly invoked. For example:

lazy val myLazyInt: Int = { println("hi"); 2 }

As you can see, using lazy notation, we’ve defined lazily an integer that stands for the literal 2 and also prints a ‘hi’ when it’s evaluated.
Apart from violating the biggest functional programming law (referential transparency) due to the insidious println, side effects, dead, destruction, blah blah …

anigif_enhanced-1822-1407333641-6

notice that, if we execute the code block, the previously mentioned ‘println’ is not executed. The block is not evaluated until any other expression makes use of our lazy integer value:

val result = myLazyInt + 3
//woa! somebody printed 'hi' and I have a brand new 5 inside 'result'

Once myLazyInt is evaluated, its value won’t be calculated again, no matter how many times it’s invoked. Therefore, the mysterious impression won’t salute us anymore:

lazy val myLazyInt: Int = { println("hi"); 2 }
myLazyInt
//"hi"
myLazyInt //nothing special happened now ...
myLazyInt //no matter how many times you invoke it...
myLazyInt //seriously, let it go...

Curious. The question that could come up is, if I define a lazy value and I pass it as a method parameter, what happens? Is it evaluated at the very same moment that the method is invoked? Maybe inside the method? That’ll depend on the way you define your method’s parameters.

Call by name vs. call by value

When defining a method, people usually define its parameter ‘by-value’, that means, that we expect the parameter to be already evaluated when it is passed to the method:

def myMethod(someInteger: Int): Int = {
  println("begin")
  val result = someInteger + 2
  println("end")
  result
}

If we invoke our method with any integer:

val n = 3
val result = myMethod(n)
//"begin"
//"end"
require(result == 5)

We just print both traces and it’s not big deal. Nothing new so far.
What happens if we now pass to the method our lazy value? In which exact moment will it print the salutation? Before or after the method traces?
Let’s try:

myMethod(myLazyInt)
//"hi"
//"begin"
//"end"

It printed it out before the method traces, which means that our lazy value was evaluated just before the method was invoked. Why does this happen? Because the way that Scala usually works needs the exact value of someInteger in order to be able to execute myMethod
It’s a pity if we want to keep myLazyInt lazy until the very last moment. How do we fix that? We’ll pass the argument ‘by-name’, that is, indicating the way the value has to be resolved instead of explicitly passing the value:

def myMethod(someInteger: => Int): Int = {
  println("begin")
  val result = someInteger + 2
  println("end")
  result
}

This way (someInteger: => Int) we indicate that our method requires as parameter an expression that, in the end, returns an integer and not an integer itself. If we now execute the method passing our non-yet evaluated lazy value:

myMethod(myLazyInt)
//"begin"
//"hi"
//"end"

Voilà! We made it. The ‘hi’ trace is not printed until the exact value of our lazy guy is required inside the method.

Some other ways to express laziness

Another way to express a lazy evaluation, which could be extremely useful, is the Function0 type:

trait Function0[+R]{
  def apply(): R
}

It’s just a function that requires zero parameters and return an only output type. It’s expressed as follows:

val f: () => Int =
  () => 2
f.apply() //2

And that’s pretty much everything…Once understood in rough outlines how laziness works in Scala, let’s move on to more interesting questions. A Lazy value, does it represent something stateful?
The answer (or more extra questions) will be available in the following post.

Peace out!

Anuncios

Valores perezosos

Por si hubieras estado en un agujero durante los últimos 10 años y no lo supieras, Scala permite gestionar valores de evaluación perezosa.

image

En Scala, podemos definir un valor que no será evaluado hasta que se le llame de manera explícita. Por ejemplo:

lazy val myLazyInt: Int = { println("hi"); 2 }

Como podéis ver, usando la notación lazy hemos definido de manera perezosa un entero que vale 2 y que imprime un ‘hola’ cuando se evalúa.
Aparte de haber violado la gran ley de la programación funcional (transparencia referencial) debido al infame println, side effects, muerte, destrucción, blah blah …

anigif_enhanced-1822-1407333641-6

fijaros que si ejecutamos el fragmento de código, dicho println no se ejecuta.
No es sino hasta que otra expresión hace uso de nuestro entero perezoso, que no se ejecuta el bloque:

val result = myLazyInt + 3
//woa! somebody printed 'hi' and I have a brand new 5 inside 'result'

Una vez calculado myLazyInt, su valor no volverá a calcularse independientemente de cuantas veces se invoque. Es decir, ya no volverá a aparecer una misteriosa impresión que nos saluda:

lazy val myLazyInt: Int = { println("hi"); 2 }
myLazyInt
//"hi"
myLazyInt //nothing special happened now ...
myLazyInt //no matter how many times you invoke it...
myLazyInt //seriously, let it go...

Curioso. La cuestión es, si yo defino un valor perezoso y lo paso a un método como argumento, ¿qué ocurre? ¿Se evalúa en el momento en que se invoca la función?¿Quizás dentro del cuerpo de la función? Eso dependerá de cómo definas los argumentos de tu método.

Call by name vs. call by value

Al definir un método, por lo general, definimos sus argumentos ‘by-value’, es decir, esperamos que el argumento ya se encuentre evaluado al pasarse al método:

def myMethod(someInteger: Int): Int = {
  println("begin")
  val result = someInteger + 2
  println("end")
  result
}

Si invocamos nuestro método con un número entero cualquiera:

val n = 3
val result = myMethod(n)
//"begin"
//"end"
require(result == 5)

Imprimimos nuestras dos trazas y ya está. Hasta aquí nada nuevo.
¿Qué ocurre ahora si le pasamos nuestro valor perezoso?¿En qué momento imprimirá “hi”?¿Antes o después de las trazas del método?
Probemos:

myMethod(myLazyInt)
//"hi"
//"begin"
//"end"

Lo imprimió antes, es decir, nuestro valor perezoso se evaluó antes de invocarse el método. ¿Esto por qué ocurre? Porque Scala, para poder ejecutar myMethod, necesita saber el valor de someInteger.
Es un fastidio si queremos mantener la evaluación de myLazyInt perezosa hasta el final. ¿Cómo lo solucionamos? Pasando el argumento ‘by-name’, es decir, indicando cómo se resolverá en el futuro el valor, pero sin pasar el valor de manera explícita:

def myMethod(someInteger: => Int): Int = {
  println("begin")
  val result = someInteger + 2
  println("end")
  result
}

De esta forma (someInteger: => Int) indicamos que le vamos a nuestro método como argumento una expresión que devolverá un entero (que no un entero). Si ahora ejecutamos el método pasándole nuestro valor perezoso no-evaluado:

myMethod(myLazyInt)
//"begin"
//"hi"
//"end"

Voilà! No es hasta el último momento en que se requiere el valor dentro del método, que no se evalúa nuestro entero perezoso.

Otras formas de expresar laziness

Otra forma que nos puede resultar muy útil para denotar que una expresión se evalúa de manera perezosa, es el tipo Function0:

trait Function0[+R]{
  def apply(): R
}

Se trata de una función que recibe 0 argumentos y devuelve un tipo de salida. Normalmente se suele notar como sigue:

val f: () => Int =
  () => 2
f.apply() //2

No hay mucho más misterio…Una vez comprendido a grandes rasgos el funcionamiento de la evaluación perezosa en Scala, pasemos a cuestiones más interesantes…¿Un Lazy es algo con estado?
La respuesta (o más preguntas) en el próximo post.

¡Agur de limón!

Scalera tips : var immutable vs. val mutable

Let’s suppose we want to define a class that has state (a list, e.g.).
If we followed the pure functional paradigm, each time we changed our instance’s state, this should return a new modified instance (with the new state).

class Foo(val state: List[Int]) {

  def mutate(n: Int): Foo =
    new Foo(state :+ n)

}

val initialFoo = new Foo(List())
assert(initialFoo.state==List())

val mutatedFoo = initialFoo.mutate(1)
assert(initialFoo.state==List())
assert(mutatedFoo.state==List(1))

…if you just think about it, it’s a case class copy method behavior.

But let’s handle the situation where we have to integrate with some legacy application and we cannot manage changes over our Foo generating a new instance.

In this case, the state is determined by the internal list, and not the Foo instance itself.

A first approach could be using a val with a mutable list(which is thread-safe):

import scala.collection.mutable
class Foo {

  private val _state: mutable.ListBuffer[Int] = 
    ListBuffer()

  def mutate(n: Int): Unit = 
    _state += n

  def state: mutable.ListBuffer[Int] =
    _state

}

austinpowers

And, on the other hand, we could use a var with an immutable list (it’s not thread-safe):

class Foo {

  private var _state: List[Int] = 
    List()

  def mutate(n: Int): Unit = 
    synchronized(_state :+= n)

  def state: List[Int] = 
    synchronized(_state)

}

Note that we’ve had to use a synchronize for protecting the state facing concurrent accesses.

Which is the best option?

Even it’s true that the second option generates more boilerplate, using the first one we could have the following situation:

val foo = new Foo
assert(foo.state==mutable.ListBuffer())
val retrievedState = foo.state += 2
assert(foo.state==ListBuffer()) //ERROR!

When returning the mutable internal list, we’ve broken the referential transparency principle and we’ve lost the access control over the state.

It’s probably dependent on the use case, but in general, the functional approach aims to generate new modified copies so potential side effects are avoided.

Scalera tips : var inmutable vs. val mutable

Supongamos que queremos definir una clase que tiene estado (una lista, por ejemplo).
Si siguiéramos el paradigma funcional puro, cada vez que modificáramos el estado de nuestra instancia, esta debería devolver una instancia nueva modificada:

class Foo(val state: List[Int]) {

  def mutate(n: Int): Foo =
    new Foo(state :+ n)

}

val initialFoo = new Foo(List())
assert(initialFoo.state==List())

val mutatedFoo = initialFoo.mutate(1)
assert(initialFoo.state==List())
assert(mutatedFoo.state==List(1))

…si te paras a pensarlo, es el comportamiento del método copy de una case class.

Pero pongámonos en el caso en que debemos integrarnos con una aplicación legacy y no podemos gestionar los cambios sobre nuestro Foo generando una nueva instancia.

En ese caso, el estado lo determina la lista interna, y no la instancia misma de Foo.

Una primera aproximación podría ser utilizar un val de tipo lista mutable (es threadsafe):

import scala.collection.mutable
class Foo {

  private val _state: mutable.ListBuffer[Int] = 
    ListBuffer()

  def mutate(n: Int): Unit = 
    _state += n

  def state: mutable.ListBuffer[Int] =
    _state

}

austinpowers

Y en la otra mano tendríamos la opción de usar un var inmutable (no es thread-safe):

class Foo {

  private var _state: List[Int] = 
    List()

  def mutate(n: Int): Unit = 
    synchronized(_state :+= n)

  def state: List[Int] = 
    synchronized(_state)

}

Fijaros que hemos tenido que hacer un synchronize para proteger el estado frente a accesos concurrentes.

¿Qué es mejor?

Si bien es cierto que la segunda opción genera mayor boilerplate, ocurre que con la primera podría darse el siguiente caso:

val foo = new Foo
assert(foo.state==mutable.ListBuffer())
val retrievedState = foo.state += 2
assert(foo.state==ListBuffer()) //ERROR!

Al devolver la lista, hemos roto el principio de transparencia referencial y perdemos el control de acceso sobre la lista.

Es probable que dependa del caso de uso de cada uno, pero en general, el enfoque funcional anima a generar nuevas copias de manera que se evitan potenciales efectos de lado.

Vals and Vars *

Immutable vs mutable

One of the first lessons that the functional world gives away is that the values we declare (val) are immutable, i.e., they can only be given a value once and cannot be modified afterwards (we’ll see later that this statement has its nuances). Henceforth, if we declared:

val myNumber: Int = 2
myNumber = 3 //Compile-time error

We wouldn’t be able to change its value. This may seem odd at first, but variables (var), commonly used in other programming languages such as Java, are completely discouraged in Scala.

var myNumber: Int = 2
myNumber = 3
println(myNumber) //Prints out '3'

What’s the point in this? If we understand that any pure function is not allowed to maintain any state, then it seems obvious that variables can have no place in them. On the other hand, you might think: ‘Yeah, but the world is not functional: as an example, I/O is essential to configure the execution of a program’… You’re absolutely right. That’s why it is recommended that, if variables need to be used, checks are carried out to see if this is absolutely necessary and if so, they should be placed at the nearest point to the application entry.
For anything else, there’s masterVal

Nounces: Stateful objects.

We said earlier that if a variable is defined as val, its value cannot be modified. We also said that some nounces could be applied to this statement. Let’s assume that we have the following piece of code:

class Foo {
  private var initialized: boolean = false
  def initialize(): Unit = {
    initialized = true
  }
  def isInitialized(): Boolean = initialized
}

If we do now instantiate a Foo-type object

val immutableFoo = new Foo
immutableFoo.isInitialized() // false
immutableFoo = new Foo //Compile-time error

If we try to reassign its value, we’ll get a compile-time error (nothing new for now). But if we call its initialize method…

immutableFoo.isInitialzed() // false
immutableFoo.initialize()
immutableFoo.isInitialized() // true

…we will have modified its internal state. So, our Foo has become in what’s called a ‘Stateful object’: an object with state. Scala tries to refuse this behaviour but we should not forget that this is the normal thing to do in Java code. Given that one of the facilities of Scala is the integration with Java, the use of Java libraries and frameworks is common practice. Our recommendation is that this pattern is avoided in Scala implementations, but we have to be aware of its likely use in other tools that we might be integrating in our project.

The best of both worlds…

One of the main virtues of Scala (scalaz people would kill us for saying this) is the existence of var.

KqsQlDV

But had you not said before that var=crap? True. But it is precisely the fact that these kinds of expressions are not forbidden what eases the transition to Scala from other languages such as Java. A transition that might be less traumatic if, at first, the same old constructions are built but with Scala’s syntax for then, further on, adopting a proper functional style.

Vals and Vars

Inmutable vs mutable

Una de las primeras lecciones con las que nos congratula el mundo de lo funcional es que, los valores que declaramos (val), son inmutables, es decir, solo se asignan una vez y no pueden ser modificados (luego veremos que esto tiene matices). Por tanto, si declarásemos:

val myNumber: Int = 2
myNumber = 3 //Compile-time error

No podríamos modificar su valor. Puede resultar extraño al principio, pero las variables (var) de uso común en otros lenguajes de programación como Java, están totalmente desaconsejadas en Scala.

var myNumber: Int = 2
myNumber = 3
println(myNumber) //Prints out '3'

¿Qué sentido tiene esto? Si pensamos que toda función pura no debe mantener estado, es obvio que no tienen cabida las variables dentro de ellas. Por otra parte, podéis pensar: “Pero el mundo no es funcional: el I/O, por ejemplo, es necesario para configurar la ejecución de un programa”. …Pues tenéis toda la razón. Por eso se recomienda, en el caso de necesitar introducir una variable, comprobar si es realmente necesario, y en caso de que así sea, tratar de ponerlas en el punto más cercano a la entrada de la aplicación. Para todo lo demás….masterVal.

Matices: Stateful objects.

Decíamos antes que el hecho de que un valor se defina como val, implica que no puede modificarse. Del mismo modo también dijimos, que esto tiene matices. Supongamos el siguiente fragmento de código.

class Foo {
  private var initialized: boolean = false
  def initialize(): Unit = {
    initialized = true
  }
  def isInitialized(): Boolean = initialized
}

Si ahora instanciaramos un objeto de tipo Foo

val immutableFoo = new Foo
immutableFoo.isInitialized() // false
immutableFoo = new Foo //Compile-time error

Si intentamos reasignar el valor, obtendremos un error de compilación (hasta aquí nada nuevo). Pero si invocamos a su método initialize…

immutableFoo.isInitialzed() // false
immutableFoo.initialize()
immutableFoo.isInitialized() // true

…habremos modificado su estado interno. Nuestro Foo es lo que se denomina un ‘Stateful object’: un objeto con estado. En Scala se procura rehusar de este comportamiento, pero no olvidemos que esto es lo habitual en código proveniente de Java, y dado que una de las facilidades que aporta Scala es la integración con Java, es muy común utilizar librerías y frameworks escritos en Java. Por tanto, de cara a nuevos desarrollos en Scala, es preferible evitar este tipo de patrón, aun siendo conscientes que es probable que al integrar con otras herramientas, podemos encontrárnoslo.

Lo mejor de los dos mundos…

Una de las virtudes que tiene Scala (la gente de scalaz nos mata), es la existencia de los var. KqsQlDV

¿Pero no habías dicho antes que var=caca? Cierto. Pero precisamente el permitir este tipo de expresiones facilita la adopción de Scala a la gente que viene de otros lenguajes como Java. Una transición puede ser menos traumática si, en principio, usando la sintaxis de Scala, utilizas las mismas construcciones del lenguaje de donde provienes para, más adelante, acabar adoptando un estilo más funcional.