Inicio > Fundamentos > La vida secreta de las funciones

La vida secreta de las funciones

Hasta el momento habiamos hablado de que en Scala, todos los valores, incluso los literales numericos como ‘1′, son de hecho objetos. Tambien habiamos hablado de que las funciones son tratadas tambien como valores: se pueden asignar, pasar como argumentos y retornar. Quizas entonces podriamos intuir que, si los valores son objetos, y las funciones son valores, entonces las funciones tambien son objetos. En efecto, esto es asi, las funciones en Scala son instancias de clases abstractas parametrizables definidas dentro del paquete scala.

Veamos un ejemplo

object Func {
   def x(s:String) : () => Unit = {
      () => {
         println(s)
      }
   }
}

Si pegamos este texto sin modificar dentro del interprete de scala:

scala> object Func {
 | def x(s:String) : () => Unit = {
 | () => {
 | println(s)
 | }
 | }
 | }
defined module Func

Ahora invoquemos Func.x, que, recordemos, devuelve una funcion:

scala> Func.x("Hello World")
res101: () => Unit = <function>

Vemos como el interprete nos dice que el resultado es  () => Unit = <function>, que significa, una instancia de funcion sin argumentos que no devuelve nada. Lo importante es que es una instancia, o sea, un objeto. Sabemos que todos los objetos (en la rama AnyRef) tienen metodos toString, asi que comprobemoslo:

scala> Func.x("Hello World").toString()
res112: java.lang.String = <function>

Entonces, de que clase es una instancia Func.x? Como habiamos dicho antes, el paquete scala define clases abstractas parametrizables de la que son instancias funciones. En este caso, Func.x es una instancia de scala.Function0[T]. Function0[T] representa funciones sin argumentos (o sea, cero argumentos, de ahi el 0), con tipo de retorno T. Por tanto, Func.x es realmente una instancia de Function0[Unit]. La clase Function0 (asi como Function1, Function2..) define un metodo especial, apply, que es donde realmente reside el codigo de la implementacion de la funcion. Veamoslo todo junto:

scala> object Func {
 | def x(s:String) : () => Unit = {
 | () => {
 | println(s)
 | }
 | }
 |
 | def y(s:String) : () => Unit = {
 | new Function0[Unit] {
 | def apply() {
 | print(s)
 | }
 | }
 | }
 | }
defined module Func

scala> Func.x("Hello World")
res113: () => Unit = <function>

scala> Func.y("Hello World")
res114: () => Unit = <function>

scala> Func.x("Hello World")()
Hello World

scala> Func.y("Hello World")()
Hello World
scala> Func.x("Hello World").apply()
Hello World

scala> Func.y("Hello World").apply()
Hello World

donde hemos definido otro metodo Func.y para definir manualmente la instancia de Function0, con identicos resultados. Tambien vemos como la invocacion de Func.x(“Hello World”)() y Func.x(“Hello World”).apply() son equivalentes.

Funciones y Metodos

Hasta el momento hemos utilizado los terminos funcion y metodo indistintamente. En la proxima entrega veremos, basandonos en lo expuesto en este post, la diferencia sutil entre estos dos mecanismos.

About these ads
Categorías:Fundamentos
  1. Aún no hay comentarios.
  1. Aún no hay trackbacks

Deja un comentario

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Conectando a %s

Seguir

Recibe cada nueva publicación en tu buzón de correo electrónico.

%d bloggers like this: