Introducción a F#

A mediados de 2010 año tuve la suerte de participar de una charla organizada por Gustavo Villavicencio sobre programación funcional, tema realmente interesante y del que no conocía demasiado. En esa ocasión vimos una introducción al tema y en la práctica trabajamos con el lenguaje Haskell.

Todo esto me despertó el interés por F#, lenguaje de .NET que si bien no es totalmente funcional, tiene algunas características del mismo (este es basicamente una implementación del lenguaje OCaml, influido por Haskell y por supuesto por C#).

Antes de comenzar con algo de práctica, les dejo la definición de Wikipedia:

F# (pronunciado F Sharp) es un lenguaje de programación multiparadigma, para la plataforma .NET, que conjunta la programación funcional con las disciplinas imperativaorientada a objetos.

Una de las características importantes es que es un lenguaje de programación multiparadigma, es decir que no es un lenguaje funcional puro, por lo que aquellos amantes de la programación funcional abstenerse de las críticas al ver los ejemplos a continuación :).

Otra característica es que continuamente utiliza la inferencia de tipos, es decir, que por ejemplo no necesitamos definir el tipo de dato de los parámetros de una función ni su valor de retorno. Sin embargo, aunque no tengamos que definir los tipos y por momentos pareciese un lenguaje dinámico, es un lenguaje fuertemente tipado.

Basta de teoría, vamos a la práctica. Algo bastante práctico que nos ofrece VS 2010 es trabajar con un archivo de script (sobre todo para hacer pruebas). Para eso dentro del menú vamos a “Archivo/Nuevo Archivo” y elegimos la opción Archivo de Script de F#.

Creando archivo de script

Creando archivo de script

Una vez creado el archivo, vamos a ver que nos van a aparecer dos pestañas, una donde vamos a escribir nuestras líneas de código (es decir nuestro script que en mi caso lo llame EjemploFSharp.fsx) y la otra pestaña llamada F#Interactive que nos permite ejecutar desde la línea de comando (esto gracias a un intérprete que corre por debajo y nos permite ir ejecutando diferentes porciones de código).

Pestañas con las cuales vamos a trabajar

Pestañas con las cuales vamos a trabajar

A comenzar a escribir líneas!… para definir “cosas” se utiliza la palabra reservada let, por ejemplo vamos a definir una función matemática para el cálculo del cuadrado:

let cuadrado x = x * x

Sencillo, no?… para poder trabajar por medio del intérprete, seleccionamos la función que escribimos y pulsamos ALT+Enter, en la consola vamos a ver lo siguiente:

val cuadrado : int -> int

Lo primero que podemos ver es como infirió el tipo de datos (tanto el parámetro de la función, como el valor que retorna, ambos integer) sin necesidad de especificarlo. Para ejecutar nuestra función escribimos el nombre de la misma, el parámetro, dos punto y coma al final y y presionamos ENTER:

> cuadrado 3;;
val it : int = 9

Veremos debajo el resultado obtenido y el tipo de dato del mismo, en nuestro caso, el número entero 9.

Otra forma de definir una función es asignándole un nombre y luego declararla utilizando una expresión lambda, por ejemplo vamos a crear la función suma:

let suma = fun x y -> x + y

En este caso estamos enlazando el identificador suma a la expresión lambda fun x y -> x + y . La función recibe dos parámetros, x e y y retorna la suma de los mismo. Si evaluamos nuestra función obtenemos lo siguiente:

val suma : int -> int -> int

Ejecutamos  y obtenemos como resultado un entero con el valor de la suma:

> suma 2 3;;
val it : int = 5

Otra de las cuestiones a tener en cuenta es los siguiente, supongamos por ejemplo que definimos una lista con los elementos del 1 al 10:

let lista = [1..10]

Esta lista es inmutable, es decir que no se le puede modificar el valor. No debemos confundirlo con una variable (que de paso no son bien vistas en programación funcional), sino que es un símbolo. Si queremos definir una variable debemos utilizar la palabra mutable, por ejemplo:

let mutable cadena = "Ya llega el 2011"

Si evaluamos su contenido nuevamente podemos ver como infiere el tipo de la variable como string:

val mutable cadena : string = "Ya llega el 2011"

Bien, una cosa muy interesante, es que podemos pasar como atributos de una función otra función, por ejemplo:

let aplicarFuncion = fun fn valor -> fn valor

El este caso vamos a aplicar la función cuadrado a el valor 3:

> aplicarFuncion cuadrado 3;;
val it : int = 9

Otra cosa que podemos hacer es retornar una función como resultado, por ejemplo:

let existeItem item =
    let functionARetornar = fun lst ->
                            List.exists (fun a -> a = item) lst

    functionARetornar

Invocamos a nuestra función y luego volvemos a invocar la función resultado:

let a = existeItem 5;;
val a : (int list -> bool)

> a [1..10];;
val it : bool = true

Por último vamos a ver un ejemplo de como trabajar con listas. En nuestro caso vamos a definir un función que sume los cuadrados de cada uno de los elementos de la lista:

let sumaCuadrados lista =  lista                          
                           |> Seq.map cuadrado                          
                           |> Seq.sum

Simple, no?!… como podemos ver por cada items aplicamos la función cuadro y finalmente sumamos el resultado de esta nueva lista. El operador |> lo que hace es tomar cada elemento de la lista y aplicarle la función que definamos a la derecha. En este caso aplica la función cuandrado y al resultado de aplicar esto se le suma todos los elementos.

Ejecutamos y vemos el resultado obtenido:

> sumaCuadrados [1..5];;
val it : int = 55

Bueno, espero que les sea útil y en los próximos posts vamos a seguir viendo otras características de F#.

Anuncios