UNIVERSIDADE FEDERAL DE SANTA MARIA CENTRO DE TECNOLOGIA SISTEMAS DE INFORMAÇÃO ELC 117 PARADIGMAS DE PROGRAMAÇÃO PROGRAMAÇÃO FUNCIONAL EXEMPLO PRÁTICO
PROGRAMAÇÃO FUNCIONAL EXEMPLO PRÁTICO Fernando Osvaldo Oliveira Junior Santa Maria, RS, Brasil 2013
PROGRAMAÇÃO FUNCIONAL EXEMPLO PRÁTICO http://stackoverflow.com/questions/13396886/why-is-linq-not-purely-functional Introdução Este trabalho procurou avaliar alguns exemplos práticos de programação funcional utilizadas atualmente. Depois de avaliar alguns exemplos em haskell: http://www.haskell.org/haskellwiki/example_code http://www.haskell.org/haskellwiki/reactive-banana/examples http://www.haskell.org/haskellwiki/haskell_in_practice E outros encontrados em F# : http://fsharp3sample.codeplex.com/wikipage?title=fsharp3samples http://fsharpsamples.codeplex.com/ http://stackoverflow.com/questions/383848/f-open-source-projects Foi analisado também o uso do LINQ e uma importante dúvida surgiu, LINQ é ou não é puramente funcional. De acordo com Christopher Bennage, em What Is Functional Programming? Part 4, Linq, http://dotnet.dzone.com/news/what-functional-programming-3, LINQ é funcional, tendo nascido sob influência de linguagens funcionais. Entretanto, de acordo com Don Stewart (Programador funcionald, PhD em ciência da computação e desenvolvedor de finanças quantitativas) num post no blog StackOverflow, http://stackoverflow.com/questions/13396886/why-is-linq-not-purely-functional LINQ não é um modelo de programação puramente funcional pois permite efeitos colaterais, sendo assim, não referencialmente transparente que é uma premissa de uma linguagem puramente funcional.
Anders Hejlsberg, Chief Architect do C# Nesta interessante entrevista, http://blogs.msdn.com/b/charlie/archive/2007/01/26/andershejlsberg-on-linq-and-functional-programming.aspx Anders explica por que LINQ e programação funcional está mudando a nossa forma de desenvolvermos aplicativos. Ele explica como as idéias de programação funcional ajudou sua equipe a dar um salto no nível de abstração na prototipagem inicial do LINQ. Ele fala sobre expressões lambda, modularidade, o uso de funções de alta ordem, árvores de expressão, programação funcional pura e concorrência. Anders diz: "Ao incorporar alguns dos conceitos funcionais torna-se possível a criação de modelos de programação de alto nível. " http://blogs.msdn.com/b/charlie/archive/2007/01/26/anders-hejlsberg-on-linq-andfunctional-programming.aspx
Alguns exemplos do uso do LINQ num ambiente comercial:
F# Um exemplo interessante foi o projeto 101 Samples (http://code.msdn.microsoft.com/f- Samples-101-0576cb9f), dentre alguns dos 101 exemplos extraí alguns que achei mais interessante: Este exemplo mostra um uso simples do "map" let ListSample2() = let data = [1;2;3;4] let r1 = data > List.map (fun x -> x + 1) printfn "Adicionando '1' usando map = %A" r1 let r2 = data > List.map string printfn "Convertendo para strings usando map = %A" r2 let r3 = data > List.map (fun x -> (x,x)) printfn "Tuplas usando map = %A" r3 Adicionando '1' usando map = [2; 3; 4; 5] Convertendo para strings usando map = ["1"; "2"; "3"; "4"] Tuplas usando map = [(1, 1); (2, 2); (3, 3); (4, 4)] Opção de uma função que indica as horas de abertura de uma loja, se houver. let OptionsSample3() = let horaabertura day = match day with DayOfWeek.Monday DayOfWeek.Tuesday DayOfWeek.Thursday DayOfWeek.Friday -> Some(9,17) DayOfWeek.Wednesday -> Some(9,19) // até mais tarde na quarta _ -> None let hoje = DateTime.Now.DayOfWeek match horaabertura hoje with None -> printfn "A loja não abre hoje" Some(s,f) -> printfn "A loja hoje abre das %02d:00 as %d:00" s f A loja hoje abre das 09:00 as 17:00 Criar um histograma das ocorrências de determinados caracteres Unicode usando o Microsoft.FSharp.Collections.Map. let SampleMap1() = let data = "The quick brown fox jumps over the lazy dog" let histogram = data.tochararray() > Seq.groupBy (fun c -> c) > Map.ofSeq > Map.map (fun k v -> Seq.length v) for (KeyValue(c,n)) in histogram do printfn "Numero de caracteres '%c' = %d" c n Número de caracteres ' ' = 8 Número de caracteres 'T' = 1 Número de caracteres 'a' = 1 Número de caracteres 'b' = 1 Número de caracteres 'c' = 1 Número de caracteres 'd' = 1 Número de caracteres 'e' = 3 Número de caracteres 'f' = 1 Número de caracteres 'g' = 1 Número de caracteres 'h' = 2 Número de caracteres 'i' = 1 Número de caracteres 'j' = 1 Número de caracteres 'k' = 1 Número de caracteres 'l' = 1 Número de caracteres 'm' = 1 Número de caracteres 'n' = 1 Número de caracteres 'o' = 4 Número de caracteres 'p' = 1 Número de caracteres 'q' = 1 Número de caracteres 'r' = 2
Este exemplo constroi uma uma lista para leitura sob demanda de um arquivo CSV usando utilitários e abstrações de E/S do.net let EnumerateCSVFile1() = // Grava um arquivo teste System.IO.File.WriteAllLines(@"teste.csv", [ "Desmond, Barrow, Market Place, 2"; "Molly, Singer, Band, 12" ]); /// Essa função constroi uma lista que realiza a separação sob demanda /// das linhas de um dado arquivo CSV let CSVFileEnumerator(fileName) = // Esta função é implementada usando uma expressão de seqüência seq { use sr = System.IO.File.OpenText(fileName) while not sr.endofstream do let line = sr.readline() let words = line.split [ ',';' ';'\t' ] yield words } // Testa no arquivo teste criado, repetindo todo o arquivo let test = CSVFileEnumerator(@"test.csv") printfn "-------Enumeration 1------"; test > Seq.iter (string >> printfn "line %s"); // Repete, dessa vez determinando o número de entradas de cada linha // Note que o arquivo é lido desde o início novamente, uma vez que cada // enumeração é independente printfn "-------Enumeration 2------"; test > Seq.iter (Array.length >> printfn "line has %d entries"); // Repete, dessa vez determinando o número de entradas de cada linha printfn "-------Enumeration 3------"; test > Seq.iter (Array.map (fun s -> s.length) >> string >> printfn "lengths of entries: %s")
Outro exemplo de projeto estudado foi o de uma calculadora http://www.c-sharpcorner.com/uploadfile/f5b919/implementing-calculator-in-wpf-usingfsharp/ Além das definições, estrutura do projeto, referências, abreviações e definições de tipo o projeto contém também um Xaml para o design gráfico da calculadora que possui esta aparência:
O código principal do projeto é a classe abaixo que gerencia todo o processamento. namespace FSharp_XAML_demo type Calculator(callback : string -> unit) = let mutable value = "" let mutable oldvalue : float option = None let mutable op : (float -> float -> float) option = None let mutable append = true //checa float member private this.getvalue() = try float value with _ -> 0. //se acrescenta dígito ao número member this.applydigit d = if append then value <- value + d else append <- true value <- d callback value //exceção do caracter de decimal. member this.setdot() = if append then value <- value + "." else append <- true value <- "." callback value //realiza operação, baseada no valor anterior e atual member this.setop newop = match op, oldvalue with Some opv, Some oldvaluev -> oldvalue <- Some(opV oldvaluev (this.getvalue())) value <- "" op <- Some newop _ -> oldvalue <- Some(this.GetValue()) value <- "" op <- Some newop callback "0" //atualiza resultado = member this.eq() = value <- match op, oldvalue with Some opv, Some oldvaluev -> opv oldvaluev (this.getvalue()) > string _ -> value oldvalue <- None op <- None append <- false callback value
Na classe onde o projeto é executado encontramos as respectivas chamadas : //carrega o xaml new () = Calc(window "Calc.xaml") //trata cada uma das operações aritméticas member this.op_click (sender : obj) (_ : eargs) = let asbutton = sender :?> btn match asbutton.content.tostring() with "+" -> calc.setop (+) "-" -> calc.setop (-) "x" -> calc.setop (*) "Ã " -> calc.setop (/) _ -> ()
Referências Christopher Bennage, What Is Functional Programming? Part 4, Linq, http://dotnet.dzone.com/news/what-functional-programming-3 http://dev.bennage.com/blog/2010/09/22/what-is-functional-programming-part-4-linq/ https://www.autobugfix.com/2010/03/is-linq-functional.html http://msdn.microsoft.com/en-us/library/bb669144.aspx http://blogs.msdn.com/b/ericwhite/archive/2006/10/04/fp-tutorial.aspx http://blogs.msdn.com/b/charlie/archive/2007/01/26/anders-hejlsberg-on-linq-andfunctional-programming.aspx