programacion funcional en el mundo real - introduccion a f#

Post on 17-Feb-2017

20 Views

Category:

Software

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

PROGRAMACIÓN FUNCIONAL EN EL MUNDOREAL

INTRODUCCIÓN A F#

Roberto Aranda López

ese.rober@gmail.com

@glomenar

PROGRAMACIÓN FUNCIONALQué es

Por qué me debería interesar

¿QUÉ ES PROGRAMACIÓN FUNCIONAL?

Un paradigma de Programación: Una manera de construir

programas.

Evita cambios de estado. Estructuras de datos inmutables.

No hay asignaciones.

Se utilizan funciones sin efectos laterales: Referencia

transparencial.

Funciones de alto nivel: Aceptan o devuelven funciones.

Las funciones son ciudadanos de primera

clase

¿POR QUÉ ME DEBERÍA INTERESAR LA PROGRAMACIÓNFUNCIONAL?

La ausencia de efectos laterales implica que es mas simple:

Paralelización

Refactorización

Reutilización

El incremento en número de cores implica la necesidad de

concurrencia.

Lenguajes tradicionalmente imperativos usan

características funcionales, por ejemplo LINQ, Expresiones

Lambda

INTRODUCCIÓN A F#

BREVE CONTEXTO HISTÓRICOEn 1970 se desarrolla el lenguaje ML (Meta Language) en la

Universidad de Edinburgh con fines académicos.

Surgen los dialectos CAML (Categorical Abstract Machine

Language) en Francia.

En 2005 Don Syme a través de Microsoft Research

Cambridge publica F# un lenguaje para .NET basado en la

familia de lenguages CAML.

¿POR QUÉ F#?Interoperable con la plataforma .NET

Multiplataforma

Código Abierto

Conciso

Robusto

Concurrente

Tiene un REPL!

CARACTERÍSTICAS PRINCIPALESEstáticamente tipado con inferencia de tipos

Multiparadigma

Proveedores de tipos: Information Rich Programming

Programación Asíncrona

Programación Paralela

Expresiones Computacionales

ENSÉÑAME EL CÓDIGO

SINTAXIS E INFERENCIA DE TIPOS 1:

2:

3:

4:

5:

6:

7:

8:

9:

10:

11:

12:

13:

let a = 2 // No hay ";"

let b = "hola" // No hay declaración de tipos

let f x = x + 2 // Una función

let f x = x + 2.0

let f x = x + "Hey you"

let f x y = // Parámetros separados por espacios

let z = x**2.0 + y**2.0 // No hay llaves, se utiliza la indenta

ción

sqrt z // Valor de retorno

Y EL HOLA MUNDO!?

UPS, LO HABÍA OLVIDADO1: printf "Hola Mundo"

DEFINICIÓN DE TIPOS

Aparte de los tipos básicos

1:

2:

3:

4:

5:

6:

7:

8:

9:

10:

11:

12:

13:

14:

15:

16:

17:

18:

19:

type tupla = string*int

type myRegistro = { Nombre:string; Edad:int }

type discriminatedUnion =

| On

| Off

| Inservible of string

type ClasePersona(Nombre:string, Edad:int) =

let mutable peso = 80.0

member this.Nombre = Nombre

member this.Edad = Edad

member this.Peso = peso

member this.GetAñodeNacimiento() = System.DateTime.Now.Year -

Edad

member this.PierdePeso(value) =

peso <- peso - value

peso

USO1:

2:

3:

4:

5:

6:

7:

8:

9:

let valorTupla = "John",14

let valorRegistro = {Nombre="John"; Edad=14}

let valorUnionType = On

let otroValorUnionType = Inservible "quemado"

let instanciaPersona = ClasePersona("John", 14)

PATTERN MATCHING1:

2:

3:

4:

5:

let enciendeEsteInterruptor unInterruptor =

match unInterruptor with

| On -> "Ya estaba Encendido"

| Off -> "Encendido"

| Inservible s -> "El Interruptor está " + s

CURRYING Y APLICACIONES PARCIALESCurrying: Transforma una función con múltiples

argumentos en una función con un argumento

En F# todas las funciones estan currificadas por defecto

Se puede llamar a una función con menos argumentos de

los que espera

Se devuelve una función que acepta los argumentos

restantes

1:

2:

3:

4:

let convierteEuros tasaCambio dinero = dinero * tasaCambio

let convierteEurosADolares = convierteEuros 1.12

let convierteEurosAPesetas = convierteEuros 166.386

COMPOSICIÓNCrear nuevas funciones a partir de otras existentes.

Operador composición:

>>

1:

2:

3:

4:

5:

6:

let grita (s:string) = s.ToUpper()

let exclama s = s + "!"

let anima = exclama >> grita

let textoPancarta = anima "vamos rafa"

"VAMOS RAFA!"

PIPELININGEnlaza la salida de una función con la entrada de otra.

Operador Pipe:

|>

1:

2:

3:

4:

5:

6:

let duplica x = 2 * x

let triplica y = 3 * y

let aplicaOperaciones x = x |> duplica |> triplica |> float |> sqrt

let resultado = aplicaOperaciones 24;;

12.0

PROVEEDORES DE TIPOSPROBLEMAS QUE RESUELVE

Los datos crudos no son tipos

Necesitamos conocer los nombres de las propiedades

Enorme cantidad de fuentes de datos

CÓMO

Mapean diferentes fuentes de datos a tipos de F#

Se producen a demanda

Representan las propiedades de los datos

Se adaptan a los cambios de esquema

Ejemplos en las Demos

PROGRAMACIÓN ASÍNCRONA 1:

2:

3:

4:

5:

6:

7:

8:

9:

10:

11:

12:

13:

14:

15:

16:

17:

18:

19:

20:

open System.Net

open System

open System.IO

let extractLinksAsync html =

async {

return System.Text.RegularExpressions.Regex.Matches(html, @"http

://\S+")

}

let downloadAndExtractLinks url =

async {

let webClient = new System.Net.WebClient()

let! html = webClient.AsyncDownloadString(Uri(url))

let! links = extractLinksAsync html

return url,links.Count

}

let links = downloadAndExtractLinks "http://www.google.com/"

let ls = Async.RunSynchronously links

PROGRAMACIÓN PARALELA1:

2:

3:

4:

5:

6:

let downloadGoogleLinks = downloadAndExtractLinks "http://www.google.com/"

let downloadWikipediaLinks = downloadAndExtractLinks "http://www.wikipedia.com/"

[downloadGoogleLinks; downloadWikipediaLinks]

|> Async.Parallel

|> Async.RunSynchronously

DEMOS

CONECTÁNDONOS AL BANCO MUNDIAL EN 5 MINUTOS 1:

2:

3:

4:

5:

6:

7:

8:

9:

10:

#r "../packages/FSharp.Data.2.2.5/lib/net40/FSharp.Data.dll"

#load "../packages/FSharp.Charting.0.90.12/FSharp.Charting.fsx"

open FSharp.Data

open FSharp.Charting

let data = WorldBankData.GetDataContext()

let pib = data.Countries.Spain.Indicators.``GDP (constant 2005 US$)``

Chart.Line pib

DISEÑO ORIENTADO AL DOMINIO 1:

2:

3:

4:

5:

6:

7:

8:

9:

10:

11:

12:

13:

14:

15:

16:

17:

18:

19:

20:

21:

module JuegoCartasBoundedContext =

type Palo = Copas | Bastos | Espadas | Oros

// | significa una elección -- toma uno de la lista

type Valor = Uno | Dos | Tres | Cuatro | Cinco | Seis | Siete

| Sota | Caballo | Rey

type Carta = Palo * Valor // * significa un par -- uno de cada

tipo

type Mano = Carta list

type Baraja = Carta list

type Jugador = {Nombre:string; Mano:Mano}

type Juego = {Baraja:Baraja; Jugadores: Jugador list}

type Reparte = Baraja -> (Baraja * Carta) // X -> Y es una función

// entrada de tipo X

// salida de tipo Y

type CogeCarta = (Mano * Carta)-> Mano

¿QUÉ FALTA EN ESTE DISEÑO?

¿Qué valores son opcionales, son todos obligatorios?

¿Cuáles son las restricciones?

¿Hay algunos valores que estén relacionados?

¿Hay alguna lógica de dominio que tenga que conocer?

1:

2:

3:

4:

5:

6:

7:

8:

9:

10:

type Contact = {

FirstName: string

MiddleInitial: string

LastName: string

EmailAddress: string

IsEmailVerified: bool // true if ownership of email address is confirm

ed

}

1:

2:

3:

4:

5:

6:

7:

8:

9:

10:

11:

12:

13:

14:

15:

16:

17:

18:

19:

module ContactExample =

type String1 = String1 of string

type String50 = String50 of string

type EmailAddress = EmailAddress of string

type PersonalName = {

FirstName: String50

MiddleInitial: String1 option

LastName: String50 }

type VerifiedEmail = VerifiedEmail of EmailAddress

type EmailContactInfo =

| Unverified of EmailAddress

| Verified of VerifiedEmail

type Contact = {

Name: PersonalName

Email: EmailContactInfo }

NUESTRAS VIEJAS AMIGAS LAS BASES DE DATOS

VOY A MANDAR UN TWEET

¿UNA APLICACIÓN WEB EN F#?

RESUMEN

¿PREGUNTAS?

top related