® Tópicos Avançados em Linguagens Computacionais – IF724 Aula Prática – FSharp (F#) Leandro Mitsuo Rodrigo Lumack [email protected] [email protected] Professor: André Santos Roteiro • • • • • Configurando o ambiente Sintaxe – Estruturas Básicas – Listas, Tuplas e Arrays – Estruturas de Controle – Expressões Condicionais – Criação de Tipos – Funções – Tipos Algébricos – Casamento de Padrões – Acessando .NET – Classes e Objetos Chamando C# de F# Chamando F# de C# Exemplos de Aplicações Configurando o Ambiente para o Desenvolvimento no VS • Primeiramente, deve-se descompactar o arquivo FSharp-1.1.13.8.zip • Em seguida, executar o arquivo InstallFSharp.msi Configurando o Ambiente para o Desenvolvimento no VS • Com o compilador instalado, agora devemos criar um projeto F# (File -> New -> Project -> Other Projects -> F# Projects) • Em seguida, devemos criar uma classe de F# (.fs file) • Agora é só escrever o código, compilar (ctrl+shift+B) e executar (F5) Desenvolvendo sem o VS • Pode-se escrever o código em algum editor de texto (Notepad++ ou Context) e salvá-lo com a extensão .fs • Com o prompt, então, podemos compilar o código executando o arquivo fsc.exe (fsc <nome do arquivo.fs>) • E em seguida, executá-lo Hello World • printf “Hello World”;; • let x = 3 + (4 * 5);; let res = (if x = 23 then "correct" else "incorrect");; printf "%s" res ;; Sintaxe - Estruturas Básicas • Constantes – Inteiros: 4096, 0xFF – String: “Hello”, “Tab\tTab” – Ponto Flutuante: 3.1215, 1000.045, 1.0e6, • Operadores – +, -, *, /, % – &&, || – =, <>, <, >, <=, >= Sintaxe – Listas • Listas – Muito utilizadas – São imutáveis • Não se pode apagar um elemento de uma lista. Podese criar uma nova lista sem este elemento [] -> Lista vazia [“Hello”; “World”] -> Lista com 2 elementos “Hello” :: [“World”] -> Lista criada com adição de elemento na frente [“Hello”] @ [“World”] -> Concatenação de listas Sintaxe – Tuplas • Tuplas – Permite agrupar valores de tipos diferentes em um único elemento (3, 4);; -> Um par de inteiros (“Hello”, 4, “World”);; -> Uma tripla de Strings e um inteiro let addThree (a,b,c) = a + b + c;; let addPairs (a,b) (d,e) = (a+d, b+e) ;; Sintaxe – Arrays • Arrays let arr = Array.create 3 "" do arr.(0) <- "hello" do arr.(1) <- " " do arr.(2) <- "world" let str = string.Join("",arr);; Sintaxe – Expressões Condicionais • Expressões Condicionais • if (4 > 3) then "Hello\n" else "Goodbye\n“;; • if (4 = 3) then AddThree(1,3,5) else 6 + 7;; Sintaxe – Estruturas de Controle • Estruturas de Controle • let y = 5;; let z = ref y;; while (!z > 3) do z := !z - 1; printf “z = %d\n" !z; done; • let x = Array.create 3 1;; for i = 0 to Array.length(x) - 1 do printf "x[%d] = %d\n" i x.(i); done; Sintaxe – Criação de Tipos • Criação de Tipos • type key_value = { key : string; value : string; } let test = { key="a"; value=“Hello" };; printf "key = %s\n" test.key;; Sintaxe – Estruturas Básicas • É possível criar tipos que recebem valores genéricos (polimorfismo paramétrico) • type ('a, 'b) key_value_g = { key : 'a; value : 'b; } let sth_g = { key=10; value="deset"; };; printf "key = %d\n" sth_g.key;; Sintaxe – Funções • Podemos criar 2 tipos de funções: – Iterativas • Precisam utilizar o símbolo ‘!’ para manipular os valores de constantes – Recursivas • Necessita do uso da palavra ‘rec’ • • Função fatorial iterativa let fac (n) = let ret = ref 1 in for i = 1 to n do ret := !ret * i; done; printf "Fatorial(%d) = %d\n" n !ret;; fac (3); Sintaxe - Funções • Função fatorial recursiva • let rec fac1(n) = if (n = 0) then 1 else n * fac1(n-1);; let r = fac1(4);; printf "Resultado = %d\n" r;; Sintaxe – Funções • Outro exemplo de função recursiva: Fibonacci • let rec fib n = if n <= 2 then 1 else fib (n-2) + fib(n-1);; • let f = fib(5);; printf "Resultado = %d\n" f;; Sintaxe – Funções • Função lambda – Podemos armazenar uma função em uma variável e chamá-la sempre que quisermos • let lambda = (fun x -> x + 1);; printf "res = %d\n" (lambda 3);; • let tmp = List.map lambda [1;2;3];; let aux = List.to_array tmp;; for j = 0 to Array.length(aux) - 1 do printf "x[%d] = %d\n" j aux.(j); done;; Exercício 1 • Crie uma função Map (ela recebe uma função e uma lista como parâmetros e retorna uma lista cujos elementos sofreram a aplicação da função) • Crie um caso de teste para validar sua função. Sintaxe – Tipos Algébricos • Casamento de Padrões • type weekday = Monday | Tuesday | Wednesday | Thursday | Friday let workRate (d:weekday) = match d with | Monday -> 1 | Tuesday -> 2 | Wednesday -> 3 | Thursday -> 4 | Friday -> 5;; let day = workRate Monday;; printf "dia = %d\n" day;; Sintaxe – Tipos Algébricos • Casamento de Padrões • type expr = Num of int | Add of expr * expr | Sub of expr * expr let rec eval e = match e with | Num n -> n | Add (x,y) -> eval x + eval y | Sub (x,y) -> eval x - eval y;; let exp = Add(Sub(Num 10,Num 5), Num 3) let result = eval exp;; printf "resultado = %d\n" result;; Sintaxe – Casamento de Padrões • Casamento de Padrões • match ("abc","def") with (x,y) -> printf "x = %s, y = %s" x y;; let (x,y) = ("abc","def") in printf "x = %s, y = %s" x y;; Sintaxe – Acessando .NET • type room = string;; type number = int;; type date = System.DateTime;; type meeting = | Personal of room * date | Phone of number * date;; let review = Phone(32,new System.DateTime(2006,05,26));; let dateOfMeeting (a:meeting) = match a with | Personal(_,d) -> d | Phone(_,d) -> d;; let data = dateOfMeeting review;; let dia = data.Day;; printf “dia = %d\n" dia;; Sintaxe – Classes e Objetos • • Classes type MyObj = class val first : int val mutable second : int new(a,b) = { first=a; second=b } member x.First = x.first member x.Second with get() = x.second and set(v) = x.second <- v member x.Write() = printf "f=%i, s=%i\n" x.first x.second end let obj = new MyObj(1,2);; obj.Write();; Exercício 2 • Crie uma classe Retangulo com atributos Largura e Altura e os métodos Área, Perímetro e Print, que imprime a largura, a altura, a área e o perímetro. • Crie uma instância dessa classe e chame o método Print. Chamando F# de C# • Para que seja possível chamar funções criadas em F# a partir de C#, é necessário criar uma biblioteca de funções F# (.dll) • Em seguida, simplesmente utilize-a como qualquer outra biblioteca (lembrando que as chamadas de função deverão seguir a sintaxe de C# -> deve-se colocar parênteses) Chamando F# de C# • • F# let rec loop n = if n <= 0 then () else begin print_endline (string_of_int n); loop (n-1) end type MyData = A | B of int * MyData let rec MyDataPrint d = match d with A -> print_endline "the end!" | B (n,d) -> print_endline (string_of_int n); MyDataPrint d let rec MyDataMap f d = match d with A -> A | B (n,d) -> B (f n,MyDataMap f d) Chamando F# de C# • C# • class Tester { static void Main() { Mydll.loop(10); Mydll.MyData x1 = Mydll.MyData.A(); Mydll.MyData x2 = Mydll.MyData.B(3,x1); Mydll.MyData x3 = Mydll.MyData.B(2,x2); Mydll.MyData x4 = Mydll.MyData.B(1,x3); Mydll.MyDataPrint(x4); Mydll.MyData x5 = Mydll.MyDataMap(FuncConvert.ToFastFunc(new System.Converter(square)), x4); Mydll.MyDataPrint(x5); if (Mydll.MyData.IsB(x5)) System.Console.WriteLine("Correct!"); } static object square(object x) { return (int) x * (int) x; } } Chamando C# de F# • open System.Windows.Forms;; let form = new Form();; let guiRefresh g = printf "refresh!\n";; form.Paint.Add(fun e -> guiRefresh e.Graphics);; let handler = new PaintEventHandler(fun sender e -> guiRefresh e.Graphics);; form.Paint.AddHandler(handler);; form.Paint.RemoveHandler(handler);; • open System.Threading;; let t = new Thread(new ThreadStart(fun () -> printf "thread started!\n"));; t.Start();; Exemplos de Aplicações – Teapot Renderer Exemplos de Aplicações - Ray Tracer Exemplos de Aplicações - Sudoku Solver Exemplos de Aplicações - Visualizador de montador de Genoma • Segundo o head of computational genomics do DOE Joint Genome Institute, Darren Platt, ele nunca viu um visualizador de montador de genoma tão rápido. – 500 linhas de código Outras Aplicações • Jogo para XBOX 360 (F# e XNA) – Dandy Dungeon • Jogo de xadrez chinês • Compilador para Java • HDFS (Hardware Design and Simulation) – Biblioteca para projeto de hardware – Implementação para FPGA´s e ASIC´s Referências • • • • • • http://www.ffconsultancy.com/dotnet/fsharp/raytracer/index.html http://www.strangelights.com/fsharp/ http://research.microsoft.com/fsharp/fsharp.aspx http://strangelights.com/fsharp/Wiki/default.aspx http://cs.hubfs.net/ http://blogs.msdn.com/dsyme/ • http://cs.hubfs.net/forums ® Tópicos Avançados em Linguagens Computacionais – IF724 Aula Prática – FSharp (F#) Leandro Mitsuo Rodrigo Lumack [email protected] [email protected] Professor: André Santos