Baixe o app para aproveitar ainda mais
Prévia do material em texto
1 1 Haskell Tâmela Freitas dos Santos (tamelas2@gmail.com) Vinicius Ribeiro dos Santos (sts.viniciusr@icloud.com) Resumo Haskell é uma linguagem puramente funcional de semântica não-rígida, uma tipagem forte e estática, focada na simplicidade e clareza do código, o que facilita sua manutenção. Neste texto serão apresentadas conceitos básicos sobre sua história, sintaxe, especificações, implementações, exemplos e também um pouco sobre suas vantagens e desvantagens. Palavras-chaves: Haskell, linguagem de programação, programação funcional. 1.1 Introdução Atualmente no mercado, diversos são paradigmas utilizados na programação, e consequentemente, para que se atenda a essa divergência de ideias, diversas também são as chamadas linguagens de programação a qual associamos ao trabalho com esses paradigmas. O foco desse trabalho é a programação em paradigma funcional especificamente voltado para linguagem Haskell. A Haskell é uma linguagem de programação puramente funcional e que foi desenvolvida para uso em diversos tipos de aplicações. Em teoria foi criada tanto para lecionar como para desenvolvimento de produtos de softwares comerciais. A linguagem é o produto que foi resultado de cerca de vinte anos de estudos na área de programação funcional, por uma sociedade de pesquisadores na área de programação e arquiteturas de computadores. O nome da linguagem veio de uma a Haskell B. Curry que foi um cientista matemático que viveu no século vinte. O propósito inicial da linguagem era ter uma proposta de ser aberta e disponível a qualquer um livremente. Mais que isso, a linguagem também visa todos os benefícios do paradigma de programação funcional, tais quais serão abordados em especial na seção de vantagens e desvantagens desse trabalho. 1.2 História Tudo começou por volta de 1930 quando os matemáticos Stephen Kleene e Alonzo Church apresentaram o λ-cálculo, que seria uma teoria de 2 funções aparentemente simples, mas muito eficiente, que tinha intensão de fundamentar teoricamente as linguagens de programação funcional. Baseado no λ-cálculo, em 1985 foi oficializado o lançamento da linguagem intitulada por Miranda, que dominou por anos o cenário mundial. Claro que após o sucesso de Miranda, começaram a emergir outras tantas linguagens, tais como Orwell, Ponder, Id, Lazy ML, Clean, Alfl, e Daisy (um dialeto de Lisp), mas ainda dois anos depois era Miranda a linguagem mais usada, principalmente por ter ganhado o mercado comercial, mas o problema principal da mesma era o fato de essa não ter um livre domínio. Pensando em criar um padrão que fosse aberto para as linguagens funcionais, foi realizada em Oregon nos EUA, em setembro de 1987, uma conferência nomeada como Linguagens de Programação Funcional e Arquitetura de Computadores (FPCA ‘87) – na tradução livre. Na prática o evento consolidaria aquelas linguagens que já existiam, enquanto também servia de principio para pósteras pesquisas acadêmicas no momento de criação de novas linguagens. O primeiro encontro da organização do comitê se deu finalmente em 1988, para discussão e definição de algumas primeiras metas da linguagem. Entre os acordados, estariam os contratos de que a linguagem necessariamente seria de ensino fácil (o mais intuitiva possível), também deveria ser escrita completamente baseada em sintaxe e semântica formais, além do principal que seria ter disponibilidade livre, de modo que fosse do acesso tanto da academia quando do mercado comercial. Assim teriam sido criadas diretrizes que unissem em uma só linguagem tudo aquilo que era oferecido antes por varias outras. Criando um modelo de linguagem funcional unificado, pratico e muito conciso. O nome Haskell foi dado à linguagem, em uma homenagem ao lógico- matemático Haskell Curry. A versão primaria da Haskell foi terminada e apresentada em 1990, sendo seguida pela versão 1.1 exatamente um ano depois, e continuando a ser lançadas novas, até que se propôs a 1.4 em 1997. Esta foi a que se manteve estável até o lançamento da tão conhecida Haskell 98, que foi divulgada em 1999. Esta já contava com uma otimização, estabilidade, e portabilidade que se mostraram revolucionarias para a época de seu lançamento, que foi acompanhado por uma biblioteca para ensino. Apenas em 2003 foi que essa versão foi submetida à uma revisão, prova de sua real eficiência durante esse período. Em 2006 foi quando começou a se estudar um sucessor do padrão 98, tido como desatualizado, então deu-se origem ao que se chama de Haskell′, ou Haskell Prime. Hoje ainda a universidade de Yale administra e estuda a linguagem, que se mantém em evolução constante. Os padrões originais de fato podem ser consultados nas implementações Hugs (interpretador) e GHC (compilador), que foram desenvolvidos na universidade de Glasgow, na Escócia. 3 1.3 Paradigma de Programação A linguagem Haskell é completamente baseada no paradigma de programação funcional, então por isso vale entender o que é esse paradigma e quais seus fundamentos. O objetivo do projeto de uma linguagem de programação funcional é imitar as funções matemáticas no maior grau possível. A primeira linguagem de programação funcional (LISP) foi criada para oferecer recursos de linguagem para processamento de listas, cuja necessidade surgiu a partir das primeiras aplicações na área de inteligência artificial. O principal motivo do surgimento de linguagens baseadas em paradigmas funcionais, como a linguagem Haskell, foi o de começar a ter processos mais simples e também mais baratos para criação e manutenção de sistemas de software com maior porte. Uma forma fácil de entender o paradigma funcional é comparar com o mais conhecido, o paradigma imperativo, entendendo seus contrastes em relação a este. No modelo de paradigma funcional qualquer código vai ser escrito estruturado na forma de um conjunto de funções sendo definidas e recebendo valores os quais o usuário vai aplicar. Enquanto isso, no modelo do paradigma imperativo, o código é composto por um segmento de instruções capazes de mudar células na memória, durante sua execução. Peculiaridades de uma linguagem puramente baseada no paradigma funcional são facilmente notadas, como por exemplo, a não alocação de forma explícita de memória, nem declaração explícita de variáveis, ou a ausência de laços. Esses são exemplos que estão em praticamente todos os códigos escritos no paradigma imperativo, e que não existem na Haskell. Não alocação, entretanto, são operações que podem ser realizadas níveis abaixo da linguagem, de forma automática, a partir do momento em que a função é chamada. Laços são substituídos por recursividade exclusivamente, e isso é considerado como a prova de que laços são homólogos a uma forma exclusiva da recursividade, que é o que se chama de recursividade reversa. Na verdade a recursividade em programação funcional tende a se manifestar de variadas formas, e na maioria das vezes é considerada como uma técnica mais poderosa que a utilização dos laços. Por isso, quase todas as linguagens imperativas também a adotam (COBOL e Fortran são das poucas exceções). 1.4 Utilização Uma das grandes vantagens da programação funcional, também abordado especialmente em outro tópico deste trabalho, é com certeza a facilidade para dar manutenção em produtos programados por uso desse paradigma. Isso se dá principalmente pela facilidade em conseguir ler o código, o que garante qualidade diretamente. E tem sido basicamente esse ponto, o que tem 4 influenciado o seu uso nas aplicações, especialmente aquelas com fins comerciais, cujos trabalhos de atualização e consequentemente modificações são constantes. Assim é muito mais fácil trabalhar com esse tipo delinguagem, visto que o trabalho técnico dos programadores é o que mais demanda tempo e precisão. Dentre as empresas que utilizam esta linguagem, as importantes são: · Intel: A Intel desenvolveu um compilador Haskell como parte de sua pesquisa que abordava em foco o paralelismo multicore em alta escala. · Google: Haskell é usado em um pequeno número de projetos internos no Google, para suporte interno à sua infraestrutura de TI e em um sistema de código aberto (Ganeti) que funciona como um gerenciador de clusterização de servidores virtuais. · Facebook: Usa Haskell internamente em algumas ferramentas. A chamada Lex-Pass é uma ferramenta usada especialmente para manipular, através de rotinas programadas, uma base de código PHP via Haskell. · The New York Times: Uma equipe do New York Times usou uma biblioteca matriz paralela de Haskell para processar imagens em 2013, na Semana de Moda de Nova York. Haskell foi escolhida principalmente por causa de sua agilidade em trabalhar matrizes numéricas e também pela facilidade de paralelização de trabalho. Além dos casos de grandes empresas, que já são consolidadas e amplamente conhecidas no mercado mundial, existem inúmeras aplicações de Haskell em outros projetos que também são notórios no meio acadêmico, e que, além disso, também foram base de pesquisa para desenvolvimento dos trabalhos em mercados comerciais. Dentre tantos podemos citar, por exemplo: · O compilador e interpretador Pugs, que foi criado por Audrey Tang, e é considerada uma versão completa da linguagem Perl 6. · A linguagem Bluespec SystemVerilog, que foi desenvolvida como uma extensão da própria Haskell. · O sistema de controle de código-fonte Darcs, que além de ser baseado em mudanças, conta com diversas inovações em suas diferenciais. · A Linux desenvolveu diversas das suas ferramentas do seu sistema em Haskell. 1.5 Sintaxe Sobre a sintaxe podemos dizer que a linguagem tenta imitar ao máximo as notações que já são populares na matemática. Assim a linguagem tenta 5 trabalhar criando sentenças lógicas para sequencias matemáticas escritas de forma muito semelhante à notação própria da matemática pura. Isso é facilmente percebido a partir das funções base da linguagem, as quais são bem familiares a quem conhece um pouco de matemática básica: sin - seno de angulo cos - coseno tan - tangente sqrt - raiz quadrada exp - exponencial log - logaritmo natural min - menor de 2 objetos dados max - maior de 2 objetos dados gcd - máximo divisor comum lcm - mínimo múltiplo comum Algumas convenções básicas importantes são apresentadas em comparação com a matemática: Alguns exemplos aplicados podem facilitar o entendimento da sitaxe: · Comprimento length [1,2,3,4,5] 5 · Obter um Prefixo take 3 [1,2,3,4,5] [1,2,3] · Remover um Prefixo drop 3 [1,2,3,4,5] [4,5] · Soma dos Elementos sum [1,2,3,4,5] 15 · Produto dos Elementos product [1,2,3,4,5] 120 · Inverter everse [1,2,3,4,5] [5,4,3,2,1] o Os comentários que também são grandes aliados do programador, e estão presentes na linguagem da seguinte forma: · Simples: Iniciados por -- e valem para toda a linha comentada. · Embricados: São marcados pelas delimitações simbólicas {- e -}. Saindo um pouco da matemática e entrando um pouco mais na aplicação da linguagem de programação, vamos entender um exemplo que 6 demonstra a estruturação de comandos em Haskell, já comparando com uma das linguagens mais populares no mercado da programação. · Somar os naturais de 1 a 10 Em linguagem C: total = 0; for (i=1; i<=10; ++i) total = total + i; Em Haskell: sum [1..10] Existem mil exemplos que poderíamos estudar aqui, mas talvez mais alguns que nos ajudariam a entender melhor a sintaxe Haskell, estejam nos exemplos abaixo: secsToWeeks secs = let perMinute = 60 perHour = 60 * perMinute perDay = 24 * perHour perWeek = 7 * perDay in secs / perWeek Nesse exemplo a tag let atribui nome para funções temporárias. Outro exemplo interessante: classify age = case age of 0 -> "newborn" 1 -> "infant" 2 -> "toddler" _ -> "senior citizen" No código a tag case cria uma condicional múltipla (semelhante ao switch case do C/C++), e o _ representa algo como ‘os demais casos’ (semelhante ao default do switch case em C/C++). Todos os exemplos mostrados nessa seção fazem parte do Prelude, que é um módulo que contém todo o conjunto de funções que podem ser consideradas nativas da linguagem Haskell, e que dessa forma, vão estar presentes em qualquer programa que as solicitem. Ainda veremos, nesse trabalho, em um uma seção especial sobre implementação que pra se aprender a programar em Haskell é preciso muita prática e também do domínio de muitas boas bibliotecas, que façam os tipos de trabalho que buscamos na linguagem. Informações sobre as bibliotecas podem ser encontradas na documentação da linguagem no site próprio da mesma. Uma outra ferramenta que está disponível gratuitamente pra ensinar a programar em Haskell é o Hoogle, um sistema web disponível no domínio da pagina da linguagem, que tem o intuito de fornecer todas as informações teóricas e técnicas da linguagem. Assim fica fácil buscar por algum erro de sintaxe, ou até mesmo como é feita uma construção em determinados casos. 7 1.6 Especificação A primeira especificação da linguagem foi elaborada em 1990. Já ocorreram diversas revisões, que resultaram nas versões 1.0 à 1.4 dos Haskell Reports, que são especificações da linguagem. A especificação mais atual é fo Report de 1998, mais conhecido como Haskell 98 Report, que já foi revisada em 2003. 1.7 Implementação O compilador mais popular de Haskell é o GHC. Quando você tiver o GHC instalado, vão ter dois programas o ghc e o ghci. O ghc compila código Haskell para executáveis e o ghci é um interpretador interativo que permite que você escreva código Haskell e tenha o retorno imediato. 1.8 Ambientes de Desenvolvimento O ghci é um interpretador muito importante para quem deseja estuda Haskell, pois através dele é possível: · Rodar trechos específicos do sistema, para testar o comportamento; · Testar as funções separadamente; · Obter informações detalhadas sobre funções e variáveis; · Carregar/Descarregar módulos e usar seus tipos e funções; · Realizar avaliações de expressões; etc Existem diversas formas de carregar nossos arquivos, no GHCI: · Passar o nome do arquivo como argumento para o comando ghci; · Usar o comando LOAD e informar o nome do arquivo a ser carregado: :load NOME ou, simplesmente, :l NOME · Usar o comando RELOAD – isso recarregará o arquivo atualmente aberto pelo ghci: :reloadou, simplesmente, :r Isso é particularmente útil quando estamos editando o arquivo e testando-o no ghci ao mesmo tempo. 1.9 Exemplos de Programas Temos alguns exemplos de softwares em notoriedade, que utilizam Haskell: · Amuzed and Zoom: Ferramenta de edição gráfica para criação de mu- charts or microcharts. Mu-charts são partes “bem definidas” de StateCharts encontrados em UML. Zoom é uma ferramenta que utiliza- 8 se dos arquivos gerados pelo Amuzed e os transformam em arquivos de texto. · Postmaster: É um software para gerenciar e-mails (Mail Transport Agent(MTA)), como o Outlook Express. · Haskell-in-Space: Jogo de asteróides. · Truth: Plataforma para verificação de sistemas distribuídos. · LambdaBot: Enorme IRC bot, extensível por plugins. · Hoogle: Uma Api Haskell para Engine de busca.Faremos um comparativo entre as linguagens C++ e Haskell para mostrar a diferença entre as linguagens Imperativas e Funcionais. Utilizaremos o algoritmo Quicksort, que é um algoritmo de ordenação muito conhecido e já implementado em diversas linguagens diferentes. O Quicksort é um algoritmo de ordenação que recebe um vetor A[p..r] e rearranja o vetor em ordem crescente, é um método de ordenação muito rápido e eficiente. Foi inventado por C.A.R. Hoare em 1960, quando visitou a Universidade de Moscovo como estudante. · Algoritmo de QuickSort Em linguagem C++: Em Haskell: Em Haskell, para definir o quicksort, precisamos definir a operação de particionamento do vetor dado um elemento especial que é chamado de pivô. O recurso de Compreensão de Listas, torna essa tarefa bastante fácil. A lista formada pelos elementos de uma lista xs menores ou iguais a x é dada por [ y | y <- xs , y <= x ] Para definir o quicksort, primeiramente, precisamos definir a operação de particionamento do vetor dado um elemento especial que é chamado de pivô. 9 Já em C++, o núcleo do algoritmo Quicksort tem o seguinte problema da separação, que formularemos de maneira propositalmente vaga: Rearranjar um vetor v[p..r] de modo que todos os elementos pequenos fiquem na parte esquerda do vetor e todos os elementos grandes fiquem na parte direita. O ponto de partida para a solução deste problema é a escolha de um pivô, digamos c. Os elementos do vetor que forem maiores que c serão considerados grandes e os demais serão considerados pequenos. É importante escolher c de tal modo que as duas partes do vetor rearranjado sejam estritamente menores que o vetor todo. A dificuldade está em resolver o problema da separação de maneira rápida sem usar muito espaço de trabalho. Notamos que em Haskell além do código ser menor e de melhor entendimento, gasta menos memória do que o código em C++. 1.10 Vantagens e Desvantagens Dentre as principais vantagens em usar a linguagem, podemos destacar: · Em Haskell, a inferência de dados é feita automaticamente, baseada no programa. Isso faz com que ele tenha um aspecto dinâmico. · Avaliação Lazy, os parâmetros são avaliados somente quando eles são utilizados nas funções. · A capacidade de definir funções que se comportam iguais, independente dos parâmetros utilizados, a essa capacidade damos o nome de Polimorfismo. · Funções podem ser tanto retornadas como resultado ou parâmetros de outras funções, ou seja, Funções de Ordem Superior. · As estruturas de dados pode ter tamanho infinito, como por exemplo as listas. Embora de fato não sejam infinitas, esta forma de avaliação de parâmetros possibilita ao programador enxergá-la dessa forma, já que pela Avaliação Lazy validada cada parâmetro quando ele for utilizado. · Não tem variáveis globais ou desvios incondicionais, tornando o código mais limpo. Entretanto alguns autores citam algumas características que podem ser notáveis como algumas desvantagens, são elas: · Execução lenta. · Alto consumo de memória. · Avaliação Lazy, só serão avaliados os parâmetros no corpo daquela função quando é utilizado, ou seja, se o parâmetro não for válido só será verificado no momento do seu uso. · Os detalhes de baixo nível da avaliação lazy são complicados, podendo perder um pouco de eficiência. 10 1.11 Conclusões Ao final do trabalho as conclusões penderam à indicadores de que a linguagem Haskell está em constante crescimento devido aos recursos que ela oferece. Apesar de ter pouca notoriedade ainda em relação à outras linguagens já consolidadas como C, Java ou C#, o sua ascendência vem sido também notória e há grandes indícios (suas peculiaridades) de que Haskell ainda vai estar no mesmo patamar que as linguagens imperativas, já citadas. Através de estudos da literatura, também foi notório o anseio que a sociedade da computação tem para com o segmento da portabilidade. O sucesso de um sistema, seja de qualquer natureza, nos últimos anos tem sido bastante definido pela sua portabilidade. Essa é uma área muito bem servida pela linguagem estudada nesse trabalho, visto que seus interpretadores e seus compiladores são suportados por qualquer sistema operacional de mercado, e também em quase toda arquitetura podemos trabalhar com a linguagem nos dias atuais. Ao fim também ficou clara a diferença que se torna evidente entre quem quer aprender os princípios de Haskell, que trata o aprendizado de outras tecnologias como o domínio de uma linguagem imperativa e, principalmente, de ferramentas matemáticas como a indução por exemplo. Não que seja um requisito, mas os conceitos básicos prévios podem adiantar muito tempo de pesquisas para se chegar onde a linguagem esta propondo o usuário. Além disso a matemática se faz fundamental não somente para aprendizado da linguagem apresentada no trabalho, mas também de diversos outros conceitos muito relevantes em computação e em linguagens de programação como um geral. Bons exemplos são árvores, listas, strings entre outras estruturas. Para aprender mais sobre a linguagem é recomendada a instalação da ferramenta Hugs que é compatível com praticamente todos os sistemas operacionais modernos, e que funciona como interpretador da linguagem, que pode ser um agente facilitador na familiarização com a sintaxe da mesma. 1.12 Referências 1. Haskell: uma linguagem de programação ideal para matemáticos, Costa, E. T., et al., CAJ/UFG, 2013. 2. Programação Funcional Haskell, Caetano, M. F., INE, 2001; 3. Programação Funcional com a Linguagem Haskell, Bois, A. R., MACS.HW, 2005; 4. A Linguagem Funcional Haskell, Piffer, M. M., et al.,UFSC, 2002 ; 5. Programação Funcional, Vasconcelos, P., DCC/FCUP, 2013; 6. Haskell Programming Language. 2011. Site ofcial da linguagem Haskell. Disponível em: http://www.haskell.org/haskellwiki/Haskell. Acessado em: 06 agosto. 2016
Compartilhar