Introducción a F#

image

Hace más de 10 años, Microsoft se encontraban preparando un nuevo lenguaje integrado de consulta LinQ. Para realizar dicho trabajo Microsoft necesitaba trabajar sobre un lenguaje funcional que permitiera un trabajo más óptimo y simple a su vez.

Mientras tanto, Don Syme, un investigador australiano que realizó su proyecto fin de carrera en la Universidad de Cambridge y era un miembro del WG2.8, un grupo de trabajo de programación funcional, se encontraba trabajando para Intel. En 1998 Microsoft contactó con Don Syme, y lo incorporó al equipo de trabajo de Visual Basic.

Debido a su relación con los lenguajes funcionales fue elegido para hacerse responsable de la creación del nuevo lenguaje funcional de Microsoft. Desde la sede de Microsoft Research de Cambridge, Don Syme comenzó a crear el nuevo lenguaje, hoy conocido como F#.


Características

F# es principalmente un lenguaje funcional, como todo lenguaje funcional los programas son colecciones de funciones que aceptan argumentos y devuelven valores.

En F# puedes elegir cuál de los 3 paradigmas es el más adecuado, o combinarlos. Puedes hacer FP, si eres un purista, o puedes fácilmente combinar funcional, imperativo, y orientado a objetos en el mismo programa y explotar las fortalezas de cada paradigma.

Su origen se encuentra en el Ocaml, un exitoso luenguaje FP Orientado a Objetos y que fue extendido para llegar a la filosofía de .Net.

F# ha sido desarrollado como un lenguaje de programación para investigación para proveer de seguridad de tipo, representación, expresividad y scripting, con todas la ventajas de correr en un moderno y de gran calidad sistema de ejecución.

Esta combinación ha sido tal éxito que el lenguaje está siendo soportado completamente en la plataforma .NET. Algunas de las razones para esto son que F# te da:

  • Conciso
  • Fuertemente Tipado
  • Inferido como ML
  • Scripting interactivo como Python
  • Portable
  • Concurrente
  • Orientado a objetos

F# es el primer ML lenguaje donde todos los tipos y valores en un programa ML pueden ser accedidos desde otros importantes lenguajes de una manera muy amigable.

F# fue desarrollado como una variante de ML que comparte núcleo con OCaml. A diferencia de otros lenguajes de scripting F# ejecuta a una velocidad cercana C# y C++. También a diferencia de muchos lenguajes de tipos inferidos, tipados estáticos, también soporta técnicas de lenguajes dinámicos. F# incluye extensiones para trabajar a través de los lenguajes y para programación orientada a objetos, y funcionar de manera similar y con las herramientas de desarrollo de .NET.

El lector ha podido quedarse con serias dudas sobre lenguajes que hemos comentado como son ML o OCaml, por ello creemos necesario describir algo de estos lenguajes.

En cuanto a ML es un lenguaje de programación de propósito general de la familiar de los lenguajes de programación funcional. Este lenguaje fue desarrollado a finales de los años 1970 en la Universidad de Edimburgo. ML es un acrónimo de Meta Lenguaje que fue creado para cálculo de predicados de primer orden y el lambda-cálculo. Por otro lado, encontramos el lenguaje Objective CAML, desarrollado y distribuido por INRIA en Francia que también admite gran cantidad de paradigmas.

Entorno de trabajo

Editor

F# puede utilizarse mediante muchas vías. Principalmente aconsejamos utilizar Visual Studio, ya que desde la versión 2003 ha sido reconocido como la mejor herramienta de trabajo para los desarrolladores. También se puede utilizar el entorno interactivo de consola fsi.exe, el cual nos permite desarrollar y explorar dinámicamente el código, soporta compilación separada y da información de depuración y optimización.

Pero sin lugar a duda trabajar sobre Visual Studio es la mejor opción soportando no sólo un entorno de desarrollo sino un increíble entorno de depuración con una gran cantidad de utilidades que nos harán el trabajo más fácil. Entre estas características encontramos comprobación de tipos, depuración de forma gráfica, formateo de la sintaxis de nuestro código, IntelliSense, CodeSense, y un sistema simple de proyectos.

Aunque no sólo podemos utilizar las herramientas anteriores,  sino que también podemos utilizar cualquiera que nos permita trabajar sobre la plataforma .net. Como las herramientas existentes para la plataforma Mono, o aplicaciones de terceros. Como última opción siempre queda utilizar el bloc de notas o cualquier aplicación similar recordando que el fichero debe de tener la extensión “.fs”.

Compilador

El compilador de F# puede compilar para todas la implementaciones de el Common Languege Infraestructure (CLI), esto es soportado mediante el Intermediate Language. Esto es una característica muy importante en los lenguajes de la plataforma .net ya que permite una gran interoperabilidad entre los lenguajes debido al MSIL el lenguaje intermedio de Microsoft.

Esto permite escribir los distintos módulos de nuestro programa en el lenguaje que creamos más conveniente y el compilador lo pasará a un lenguaje intermedio para después ser interpretado sobre el motor de .NET Framework.

Plataforma

Cuando trabajemos sobre F# lo podemos hacer en la mayoría de plataformas que soportan el .net Framework. Por tanto podemos trabajar no sólo en los sistemas operativos Windows, sino que también existen frameworks para MacOS y Linux. Este último gracias a la plataforma MONO, que se encargan de desarrollar el Framework para funcionar sobre Linux. Como nota, podemos decir que mientras realizábamos este proyecto encontramos más gente trabajando en F# sobre Mono que sobre los sistemas Windows. Aunque esto se debe también a su poco tiempo en el mercado.

Ejemplo de potencia de F# según Don Syme

Además para mostrar la potencia de F# Don Syme comentó una aplicación que había desarrollado y así compararla con la potencia de C#.

Enunciado: Una aplicación que analiza millones de feedbacks. Es sistema lee los datos desde una BD SQL Server y escribe los resultados en un fichero de Matlab.

Teniendo los siguientes resultados, que muestran claramente la superioridad de F# para este tipo de aplicaciones. Y siendo por tanto F# una opción muy recomendable para el trabajo diario de un desarrollador.

Sintaxis de F#

Para describir las principales características sintácticas hemos decidido dividir entre las características propias de la programación declarativa, la programación imperativa, y la programación orientada a objetos. En cada una de estas metodologías incluimos un ejemplo de cada característica y alguna nota aclaratoria para que pueda ser usador rápidamente.

Lo primero que necesitamos siempre incluir en nuestro programa en F# será:

// Activamos la sintaxis ligera

#light

// Namespace standard

open System

Programación Declarativa

Computaciones simples

// En F# la palabra clave para la asignación será let.

let int1 = 1

let int2 = 2

let int3 = int1 + int2

Funciones de enteros

/// Una función de enteros

let f x = 2*x*x – 5*x + 3

/// El resultado de una computación simple

let result = f (int3 + 4)

/// Otra función de enteros

let increment x = x + 1

/// Factorial de un entero

let rec factorial n = if n=0 then 1 else n * factorial (n-1)

let var = factorial 4

Tuplas

// Una simple tupla de enteros

let pointA = (1, 2, 3)

// Una simple tupla de entero, cadena y float

let dataB = (1, "fred", 3.1415)

/// Función que intercambia el orde de los 2 valores de la tupla

let Swap (a, b) = (b, a)

Booleaos

let boolean1 = true

let boolean2 = false

let boolean3 = not boolean1 && (boolean2 || false)

Strings

/// Una cadena simple

let stringA  = "Hello"

/// Otra cadena simple

let stringB  = "world"

/// Concatenación de cadenas

let stringC  = stringA + " " + stringB

printf "%s" stringC

/// "Hello world" computada usando una función de una librería de .NET

let stringD = String.Join(" ",[| stringA; stringB |])

Listas

/// Lista vacía

let listA = [ ]         

/// Una lista con 3 enteros

let listB = [ 1; 2; 3 ]   

/// Operación ‘cons’ ::

let listC = 1 :: [2; 3]  

/// Computar la suma de una lista de enteros utilizando Match para declarar una función por partes.

let rec SumList xs =

    match xs with

    | []    -> 0

    | y::ys -> y + SumList ys

/// Suma de la lista.

let listD = SumList [1; 2; 3]

/// La lista de enteros entre 1 y 10 inclusive.

let oneToTen = [1..10]

Arrays

/// Crear una array

let arr = Array.create 4 "hello"

arr.[1] <- "world"

arr.[3] <- "don"

/// Longitud del array

let arrLength = arr.Length      

//Extraer el subarray

let front = arr.[0..2]

Programación Imperativa

F# contiene recursos de la programación imperativa, añadiendo cambios de estado, tipos, registros, llamadas a métodos estáticos, creación de objetos, control de flujo y eventos.

Funciones

/// Cuadrado de un valor

let Square x = x*x            

// Operaciones sobre listas como Map (para realizar una operación sobre cada elemento de la lista pasada como argumento.

let squares1 = List.map Square [1; 2; 3; 4]

let squares2 = List.map (fun x -> x*x) [1; 2; 3; 4]

Registros

type Tarjeta = { Nombre  : string;

              Telefono : string;

              Ok    : bool }

let TarjetaA = { Nombre="Alf"; Telefono="(206) 555-8257"; Ok = false}

let TarjetaB = { TarjetaA with Telefono="(206) 555-4112"; Ok = true }

let ShowCard c = c.Nombre + "Phone: " + c.Telefono + (if not c.Ok then " (unchecked)" else "")

Control de flujo

// Tenemos bucles while, for y do, y la condicional if.

#light

let words = [| "Red"; "Lorry"; "Yellow"; "Lorry" |]

for word in words do printf "%s" word

Librerias .NET

// Este es un ejemplo de uso de una librería de .Net como System.IO.File para la creación de un fichero de texto.

let writeToFile() =

    let file = System.IO.File.CreateText("test.txt") in

    try

        file.WriteLine("Hola desde declarativa avanzada")

    finally

        file.Dispose()

writeToFile()

Eventos:

// Ejemplo de uso de el evento Elapsed del Objeto Timer, de tal manera que una vez configurado un temporizador a 3 segundos, el evento que lanza sea capturado y escriba un mensaje para el usuario.

#light

open System.Timers

let timer =

    let temp = new Timer()

    temp.Interval <- 3000.0

    temp.Enabled <- true

    let messageNo = ref 0

    temp.Elapsed.Add(fun _ ->

        let messages = ["bet"; "this"; "gets"; "really"; "annoying"; "very"; "quickly";]

        messageNo := (!messageNo + 1) % (List.length messages))

    temp

timer.Enabled <- false

Programación Orientada a Objetos

El objetivo es encapsular la implementación y el estado. Conseguimos una mejor estructura del  programa. Además tenemos herencia, muy útil al trabajar con GUIs, es decir, para poder crear las interfaces gráficas como se realizan con otros lenguajes de .net.

F# tiene:

·         Interfaces

·         Casting

·         Clases

Tipos: clases

/// Clase con un vector de 2 dimensiones

type Vector2D(dx:float, dy:float) =

    let length = sqrt(dx*dx + dy*dy)

    member v.DX = dx

    member v.DY = dy

    member v.Length = length

    member v.Scale(k) = Vector2D(k*dx, k*dy)

Tipos: interfaces

///  Ejemplo de una interfaz simple con dos funciones abstractas Suma y Div.

type INumbers =

    abstract Suma: int -> int

    abstract Div: int -> float

Ejemplo. Suma de los cuadrados de una lista

Construiremos una función que sume los cuadrados de una lista dada. La construcción de la función la podemos realizar de varias maneras diferentes, según nos convenga. En este caso hemos elegido de forma recursiva y de forma iterativa.

// Suma de cuadrados recursiva

let rec sumOfSquaresF nums =

    match nums with

    | [] -> 0.0

    | h::t -> sqr h + sumOfSquaresF t

// Suma de cuadrados iterativa

let sumOfSquares nums =

    nums

    |> Seq.map sqr

    |> Seq.sum

En la suma de cuadrados recursiva simplemente hemos declarado el caso base y la sucesión recursiva de los restantes elementos. Para la forma iterativa, llamamos a la función map sobre la lista de entrada aplicandole a todos los elementos su propio cuadrado y finalmente sumamos todos los elementos a tarvés de la función sum.

Las salidas para ambas funciones sober la lista [1,2,3,4] es la siguiente:

> sumOfSquaresF [1.;2.;3.;4.];;

val it : float = 30.0

> sumOfSquares [1.;2.;3.;4.];;

val it : float = 30.0

Acerca de ArturoMezDa

Ing.Sistemas Computacionales

Publicado el 1 septiembre, 2010 en Alternativas, Desarollo, Programacion, Que Es ?, Software, Tecnologias, Tutoriales, windows y etiquetado en , . Guarda el enlace permanente. Deja un comentario.

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: