Inicio > Fundamentos > Funciones de orden superior

Funciones de orden superior

Retornemos brevemente al mundo de HelloWorld. Pero esta vez, lo haremos mas complicado.


object HelloWorldFunc {
   def combine (f1: () => Unit, f2: () => Unit) : () => Unit = {
      () => {
         f1()
         f2()
      }
   }
   def Hello() {
      print("Hello ")
   }
   def World() {
      print("World!")
   }

   def main(args: Array[String]) {
      combine(Hello, World)()
   }
}

Aunque no es la manera optima de escribir Hello World! por pantalla este ejemplo incluye algunas caracteristicas importantes.

Recordemos nuestro uso del termino valor para referirnos a todo aquello que puede ser asignado, pasado como argumento o retornado de una funcion, o algo sobre lo que se opera. Pues bien, en Scala las funciones son valores. Esta caracteristica tan importante, y algunas  otras que no mencionare ahora, hacen de Scala un lenguaje hibrido oo-funcional[1].

Combinando

Vemos que en el ejemplo se definen dos funciones que escriben por pantalla, una para escribir “Hello“, y otra para escribir “World!“. La funcion mas interesante es combine, que recibe como argumentos dos funciones, y devuelve otra funcion: la compuesta for la ejecuccion de sus dos argumentos, uno despues del otro. Por tanto, para escribir Hello World!, la funcion main llama a combine pasandole Hello y World, y recibe como retorno una funcion que combina las dos. Este retorno, que es una funcion, es a su vez invocado, y es por esto que tenemos dos parentesis finales en esa linea

   def main(args: Array[String]) {
      combiner(Hello, World)()
   }

Se denominan funciones de orden superior (higher order functions) aquellas que reciben funciones como parametro o tienen como retorno una funcion. En este caso combine es una funcion de orden superior por partida doble, al tener las dos caracteristicas. La practica de programar utilizando funciones de orden superior se llama higher order programming[2], y es un estilo muy expresivo tipico de lenguajes funcionales.

Uso real

Aparte de para complicar codigo de HelloWorld, existen otros usos del estilo funcional. Un ejemplo tipico es la implementacion de una funcion generica de ordenamiento (sort) de lista[3]. Separar la problematica del ordenamiento en dos partes, una la que invoca un comparador para determinar la posicion de cada elemento, y otra el comparador en si, permite que la primera parte sea generica y abstraida de la naturaleza exacta de los elementos a ordenar. Asi, una funcion de ordenamiento generica recibe como parametro un comparador especializado, una funcion que establece el orden entre dos elementos de un tipo especifico.

Sintaxis de tipo funcion

La sintaxis argumentos => retorno sirve para definir un tipo funcion, con argumentos argumentos y retorno tipo retorno. En este caso tenemos que combine recibe dos argumentos, los dos funciones sin argumentos que tampoco retornan nada. A su vez, combine retorna una funcion sin argumentos que no retorna nada. Por tanto la sintaxis completa, tanto para los argumentos como para el retorno de combine es

.. (f1: () => Unit, f2: () => Unit) : () => Unit ..

Retorno, funciones anonimas y closures

En Scala no existe el equivalente a return para retornar de una funcion. Al estilo de los lenguajes funcionales, el retorno de una funcion en Scala es el resultante de evaluar la ultima expresion del cuerpo de la misma. Por tanto el retorno de combine es

() => {
    f1()
    f2()
}

lo cual define inline una funcion anonima cuyo comportamiento es invocar primero f1 y despues f2. Las funciones anonimas son un mecanismo importante que posibilitan la definicion agil y flexible de comportamiento alli donde sea necesario sin tener que declararlas anteriormente. Tipicamente son bloques de codigo utilizados en ambitos circunstritos del codigo, para lo que no hace falta una definicion ni una referencia para uso posterior. Un uso familiar para los que conozcan Java es como callbacks, aunque en Java,  al no existir las funciones de manera independiente, se tienen que empaquetan dentro clases anonimas, que hacen de meros vehiculos.

Tambien decir brevemente que esta funcion anonima hace de closure[4]. Notese que los argumentos f1 y f2 son accesibles por la funcion anonima aun cuando el ambito de combine ya ha expirado.

[1] Los lenguajes funcionales estan cobrando interes recientemente por su capacidad para expresar flujos de ejecuccion concurrente y asi aprovechar arquitecturas multi nucleo, por las que transitara la industria de los microprocesadores en los proximos años.

[2] http://en.wikipedia.org/wiki/Higher_order_programming

[3] http://www.scala-lang.org/docu/files/api/scala/util/Sorting$object.html

[4] http://en.wikipedia.org/wiki/Closure_(computer_science)

Anuncios
Categorías:Fundamentos
  1. Aún no hay comentarios.
  1. No trackbacks yet.

Responder

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 )

Google+ photo

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

Conectando a %s

A %d blogueros les gusta esto: