Introdução ao F# Michel Pavan Macedo [email protected] O que é o F#? • Linguagem .NET – É possível usar qualquer biblioteca .NET do F# – É possível usar qualquer biblioteca F# de outras linguagens para .NET • Combina dois paradigmas de programação importantes – Programação Orientada a Objeto – Programação Funcional – Também muito útil para script Por que F#? • Programação funcional é o foco da linguagem • Que linguagens utilizaremos em um futuro próximo? – Algumas características do F# poderão ser incorporadas em outras linguagens e bibliotecas • Desenvolvida pela Microsoft Research – Bem testada e otimizada – Comunidade crescente • Graças ao .NET pode ser utilizada como parte de um projeto maior Agenda • • • • • F# #light F# funcional F# orientado a objetos F# interativo F# real Sintaxe • Estaticamente tipado (como o Java e C#, não como Ruby, Python e JavaScript) – Tipos são inferidos pelo contexto // valor inteiro (int) let n = 42 // valor do tipo texto (string) let str = "Hello world!" // Função (int -> int) let add10(n) = n + 10 – Usa tipos parametrizados quando possível // Função identidade ('a -> 'a) let id(sth) = sth Valores • É possível representar 0, 1 ou mais valores // valor do tipo unit (unit) let nada = () // valor inteiro (int) let numero = (5) // tupla de inteiro e string (int * String) let tupla = (5, “Cinco”) // um valor Int32 e um valor String let valor, nome = tupla • Algum valor ou nenhum valor // Função de tipo “int -> int option” let positivo n = if n > 0 then Some(n) else None Funções • Toda função tem um parâmetro e um retorno // recebe unit, retorna unit: unit -> unit let imprime5() = printf “%s é igual a %d” “cinco” 5 // recebe inteiro, retorna inteiro: int -> int let maisUm(n) = n + 1 // recebe inteiro, retorna inteiro: int -> int let maisDois n = n + 2 // recebe tupla de inteiros (int * int) -> int let soma(a, b) = a + b // recebe tupla de inteiros int -> int -> int let potencia a b = a ** b Discriminated Union • Discriminated union em F# type Option<'T> = | None | Some of 'T type List<'T> = | Nil | Cons of 'T * List<'T> Option<'T> Option<'T>.None Option<'T>.Some valor: 'T DEMO Interativo Agenda • • • • • F# #light F# funcional F# orientado a objetos F# interativo F# real Funcional vs Imperativo • Abordagem imperativa – Atribuição é a operação mais importante • Abordagem funcional – Baseado em recursividade – Todas as estruturas são imutáveis por padrão – Funções funcionais puras não tem efeitos colaterais • Fácil de testar e depurar • Fácil de paralelizar Funcional vs Imperativo • Em F# você pode combinar ambas abordagens – Imperativo é bom para interoperabilidade com .NET • Funcional // Fatorial (funcional) let rec fat_f n = if (n = 0) then 1 else n * fat_f(n – 1) • Imperativo // Fatorial (imperativo) let fat_i n = let mutable ret = 1 for i = 1 to n do ret <- ret * i done ret Imutabilidade • Além de unidades e records open System // declara unidades de medida [<Measure>] type copinho [<Measure>] type litro [<Measure>] type dia // declara constante de conversão let copinhoPorLitro : float<copinho/litro> = 6.0<copinho/litro> // declara função de conversão let emLitros (c:float<copinho>) = c / copinhoPorLitro // declara um record type Programador = { Nome: String; Cafe: float<litro/dia> } // instancia um programador let euDoPassado = { Nome = “Michel”; Cafe = 1.5<litro/dia> } // tenta alterar o programador, mas ele é imutável euDoPassado.Cafe <- (emLitros 6<copinho>) / 1.0<dia> // instancia um novo programador let eu = { euDoPassado with Cafe = emLitros(6<copinho>)/1.0<dia> } DEMO Tutorial Introdutório Agenda • • • • • F# #light F# funcional F# orientado a objetos F# interativo F# real De Amanda Laucher e Josh Graham • Problema: encontrar a passagem mais barata para uma determinada viagem // direção type direction = |To |From |Return // classe da passagem type ticketClass = |Standard |First // passagem type ticket = {Price:decimal; Class:ticketClass; Direction:direction} continuação type Journey (tickets) = let lowestPrice cls dir = (tickets |> List.filter(fun x -> x.Class = cls && x.Direction = dir) |> List.min).Price let getCheapestList cls dir = tickets |> List.filter (fun x -> x.Class = cls && x.Direction = dir && x.Price = (lowestPrice cls dir)) let getTicketsByClass cls = tickets |> List.filter (fun x -> x.Class = cls) let getTicketsByDirection dir = tickets |> List.filter (fun x -> x.Direction = dir) continuação member member member member member member member if x.CheapestStdTo = getCheapestList Standard To x.CheapestFirstTo = getCheapestList First To x.CheapestStdFrom = getCheapestList Standard From x.CheapestFirstFrom = getCheapestList First From x.CheapestStdReturn = getCheapestList Standard Return x.CheapestFirstReturn = getCheapestList First Return x.StandardCheapestBoth = ((lowestPrice First To) + (lowestPrice First From)) > (lowestPrice First Return) then x.CheapestFirstReturn else x.CheapestFirstFrom @ x.CheapestFirstTo member x.AllOutwardTickets = getTicketsByDirection To member x.AllInwardTickets = getTicketsByDirection From member x.AllReturnTickets = getTicketsByDirection Return member x.AllStandardTickets = getTicketsByClass Standard member x.AllFirstTickets = getTicketsByClass First Agenda • • • • • F# #light F# funcional F# orientado a objetos F# interativo F# real F# interativo • Três motivos porque eu amo Shell – Consiste apenas de um core de operadores – Esses poucos operadores são para trabalhar com pipes – É fácil e prático de testar • O que faz uma linguagem de script? – O código deve ser o mais conciso possível – Normalmente são interpretadas (F# é compilado) – F# tem verificação estática DEMO Visualização 3D Agenda • • • • • F# #light F# funcional F# orientado a objetos F# interativo F# real De um slide de Don Syme I’ve been coding in F# lately, for a production task. F# allows you to move smoothly in your programming style... I start with pure functional code, shift slightly towards an objected-oriented style, and in production code, I sometimes have to do some imperative programming. I can start with a pure idea, and still finish my project with realistic code. You’re never disappointed in any phase of the project! Julien Laugel, Chief Software Architect, www.eurostocks.com DEMO ASP.NET MVC WebForms (C#) Razor (C#) Referências • HubFS (comunidade de F#) http://cs.hubfs.net/ • InfoQ (tem ótimas palestras de F#) http://www.infoq.com/ • Try F# http://www.tryfsharp.org/ • Exemplos de F# (aqueles dessa apresentação) http://fsharpsamples.codeplex.com/ Referências • Bastantes tutoriais de recursos do F# http://leibnizdream.wordpress.com/ • Ótimo blog de F# (inclusive slides base para essa apresentação) http://www.tomasP.net/ • Ótimo livro de F# http://www.amazon.com/Real-World-FunctionalProgramming-Examples/dp/1933988924