Haskell (linguagem de programação)
As referências deste artigo necessitam de formatação. (Agosto de 2022) |
Haskell | |
---|---|
Paradigma | |
Surgido em | 1990 (33–34 anos) |
Criado por |
|
Estilo de tipagem |
|
Principais implementações | |
Dialetos |
|
Influenciada por | |
Influenciou | |
Extensão do arquivo |
|
Página oficial | www |
Haskell é uma linguagem de programação puramente funcional, de propósito geral, nomeada em homenagem ao lógico Haskell Curry. Como uma linguagem funcional, a estrutura de controle primária é a função; a linguagem é baseada nas observações de Haskell Curry[2][3] e seus descendentes intelectuais.[4][5] Seu último padrão semi-oficial é o Haskell 98, destinado a especificar uma versão mínima e portável da linguagem para o ensino e como base para futuras extensões.
Haskell é a linguagem funcional sobre a qual mais se realizam pesquisas atualmente. Muito utilizada no meio acadêmico, ė uma linguagem relativamente nova, derivada de outras linguagens funcionais, como por exemplo Miranda e ML. Ela se baseia em um estilo de programação em que se enfatiza mais o que deve ser feito (what) em detrimento de como deve ser feito (how). É uma linguagem que possui foco no alcance de soluções para problemas matemáticos, clareza, e de fácil manutenção nos códigos, e possui uma variedade de aplicações e apesar de simples é muito poderosa.
História
[editar | editar código-fonte]O conceito de avaliação preguiçosa já estava difundido no meio acadêmico desde o final da década de 1970. Esforços nessa área incluíam técnicas de redução de grafo e a possibilidade de uma mudança radical na arquitetura de von Neumann.[6] Após o lançamento de Miranda em 1985, diversas outras linguagens funcionais de semântica não rígida proliferaram, como Lazy ML, Orwell, Alfl, Id, Clean, Ponder e Daisy (um dialeto de Lisp). Mesmo após dois anos, Miranda ainda era a mais usada, mas não estava em domínio público.
Em setembro 1987 foi realizada uma conferência Functional Programming Languages and Computer Architecture (FPCA '87), no Oregon. O consenso foi a criação de um comitê com o objetivo de construir um padrão aberto para tais linguagens.[7] Isso consolidaria as linguagens existentes, servindo como base para pesquisas futuras no desenvolvimento de linguagens.[8] A primeira reunião do comitê foi realizada em janeiro de 1988, e algumas das metas da linguagem foram discutidas. A linguagem deveria ser de fácil ensino, deveria ser completamente descrita através de uma sintaxe e semântica formal, deveria estar disponível livremente. Haskell foi criada da necessidade de unir as outras linguagens do mesmo paradigma em uma só.
Dentre os principais objetivos deste comitê, ao projetar essa nova linguagem, estavam suas especificações:
- Ser viável para o ensino, pesquisa e aplicações, incluindo sistema de larga escala;
- Ser completamente descritiva via publicação no tocante à sua sintaxe e sua semântica;
- Não ser proprietária, tal que qualquer um pudesse implementá-la e distribuí-la;
- Basear-se em ideias que envolvessem o senso comum;
- Reduzir a diversidade desnecessária de outras linguagens funcionais.
A primeira versão de Haskell foi definida em 1 de abril de 1990.[9] Seguiu-se a versão 1.1 em agosto do ano seguinte, a versão 1.2 em março de 1992, a versão 1.3 em maio de 1996 e a versão 1.4 em abril de 1997.[10] Esforços posteriores culminaram no Haskell 98, publicado em janeiro de 1999 e que especifica uma versão mínima, estável e portável da linguagem e a biblioteca para ensino. Esse padrão sofreu uma revisão em janeiro de 2003.[11]
A linguagem continua evoluindo, sendo as implementações Hugs e GHC consideradas os padrões de facto. A partir de 2006 começou o processo de definição de um sucessor do padrão 98, conhecido informalmente por Haskell′ ("Haskell Prime").[12]
Haskell 1.0 até 1.4
[editar | editar código-fonte]A primeira versão do Haskell (“Haskell 1.0”) foi definida em 1990. Os esforços do comitê resultaram em uma série de definições da linguagem (1.0, 1.1, 1.2, 1.3 e 1.4).
Haskell 98
[editar | editar código-fonte]No final de 1997, as séries culminaram no Haskell 98, com a intenção de especificar uma versão mais estável e portátil da linguagem acompanhada de uma biblioteca padrão para ensino, e como base para extensões futuras. O comitê expressou satisfação em criar extensões e variantes de Haskell 98 a partir da adição e incorporação de atributos experimentais.
Em fevereiro de 1999, o padrão da linguagem foi originalmente publicado em um relatório chamado de The Haskell 98 Report. Em janeiro de 2003, uma versão revisada foi publicada como Haskell 98 Language and Libraries: The Revised Report. A linguagem continuou a evoluir rapidamente, com a implementação do Compilador Glascow Haskell representando o padrão atual.
Haskell 2010
[editar | editar código-fonte]No começo de 2006, iniciou-se o processo de definir um sucessor para o padrão Haskell 98, informalmente chamado de Haskell Prime. A intenção era de que viesse a ser um processo incremental para revisar a definição da linguagem, produzindo uma revisão nova anualmente. A primeira revisão, chamada de Haskell 2010, foi anunciada em novembro de 2009, e publicado em julho de 2010.
Haskell 2010 é uma atualização incremental da linguagem, incorporando atributos muito utilizados e não controversos previamente ativados por bandeiras específicas do compilador.
- Módulos hierárquicos. Módulos consistem de sequências de identificadores em maiúsculo separadas por pontos, ao invés de apenas um identificador. Dessa maneira é possível nomear os módulos de maneira hierárquica (Data.List ao invés de List), apesar de que módulos técnicos ainda estão em um espaço monolítico. Essa extensão foi especificada como um adendo do Haskell 98 e na prática foi universalmente usado.
- A interface de função estrangeira (FFI), permite ligações para outras linguagens de programação. Apenas ligações para C são especificadas no relatório, mas o design permite para outras ligações de linguagens. Para suportar isso, declarações de tipos de dados não permitem conter construtores, admitindo tipos para dados estrangeiros que não podem ser feitos em Haskell. Essa extensão foi previamente especificada no adendo do relatório de Haskell 98 e vastamente utilizado.
- Os chamados padrões n+k (definições da forma fact (n+1) = (n+1) * fact n) não são mais permitidos. Esta sintaxe enganava a semântica, onde no código parecia ter sido usado o operador (+), na realidade utilizava-se (-) e (>=).
- As regras de inferência de tipo foram afrouxadas para permitir que mais programas chequem o tipo.
- Alguns assuntos da sintaxe (mudança na gramática formal) foram corrigidos: proteções de padrões foram adicionadas, permitindo correspondências entre padrões e proteções; a ordem de operações matemáticas foi especificada de uma maneira mais simples do que na prática; um caso na interação de operadores e comentários da sintaxe léxica da linguagem foi endereçada; e a interação da notação do e if-then-else foi ajustada para eliminar erros inesperados de sintaxe.
- A diretriz da linguagem foi especificada. Por volta de 2010, dúzias de extensões da linguagem estavam sendo vastamente utilizadas, e GHC (entre outros compiladores) permitiram a diretriz especificar extensões com uma lista de identificadores. Compiladores de Haskell 2010 necessitavam da extensão Haskell2010, e eram encorajadas a suportar outras várias que correspondiam a extensões adicionadas no Haskell 2010.
Características
[editar | editar código-fonte]Características do Haskell incluem o suporte a funções recursivas e tipos de dados, casamento de padrões, list comprehensions, guard statements e avaliação preguiçosa, esta, um elo em comum entre os diversos grupos de desenvolvimento da linguagem.[13] A combinação destas características pode fazer com que a construção de funções que seriam complexas em uma linguagem procedimental de programação, torne-se uma tarefa quase trivial em Haskell. Segundo dados de 2002, é a linguagem funcional sobre a qual mais pesquisa está sendo realizada. Muitas variantes têm sido desenvolvidas: versões paralelizáveis do MIT e Glasgow, ambas chamadas Parallel Haskell, outras versões paralelas e distribuídas chamadas Distributed Haskell (anteriormente Goffin) e Eden, uma versão chamada Eager Haskell e várias versões orientadas a objetos: Haskell++, O'Haskell e Mondrian.
Uma versão educacional do Haskell chamada Gofer, foi desenvolvida por Mark Jones. Ela é oferecida pelo HUGS. Existe também uma versão do Haskell que permite orientação a aspectos (POA), chamada AspectH.
A linguagem de programação Haskell é fundamentada em Lambda Cálculo, que serve como base no desenvolvimento do artigo e apresenta um único tipo, as funções. Haskell apresenta um tipagem forte e estática, onde as expressões são ligadas a um mesmo tipo em tempo de compilação; e apresenta o polimorfismo universal, e possui um tipo genérico e a mesma definição é usada para vários tipos.
Sintaxe
[editar | editar código-fonte]Em Haskell existem apenas funções, e todas as funções são unárias. O que, em outras linguagens de programação seriam funções binárias, ternárias, etc, em Haskell são funções cujo valor de retorno são outras funções - o que se chama currying, termo derivado de Haskell Curry.
Uma função que, dados dois números, retorna sua soma poderia ser declarada como:
soma x y =x+y
O que parece ser uma função binária é, logicamente, uma função unária (soma, cuja entrada é x) que retorna outra função. Em outras palavras, soma x é a função unária que, dado y retorna x + y, e soma é a função unária que, dado x, retorna x +.
Em Haskell não existem variáveis globais, apenas funções e variáveis locais, definidas dentro do escopo de cada função.
Também não há estruturas de loop, ou instruções do tipo goto.
O if é implementado através de |, que significa a restrição do domínio do argumento da função.
O exemplo abaixo mostra uma implementação do fatorial que usa a recursividade e o if:
fat 0 = 1
fat n | n > 0 = n*fat(n-1)
Em outras palavras: a primeira linha diz que o fatorial de zero é um; a segunda linha diz que o fatorial de um número n qualquer, desde que n seja maior que zero, pode ser calculado a partir do fatorial de (n-1). Esta implementação não é eficiente, mas serve como exemplo didático.
Listas
[editar | editar código-fonte]Há duas funcionalidades importantes para a construção de listas. A primeira é a list comprehension, que permite construir listas sob forma de conjuntos. Por exemplo, o código [ x | x <- [0..], x^2>3 ]
cria uma lista de elementos x
a partir do gerador <- [0..]
(o conjunto dos números naturais), que atendam o predicado x^2>3
(o símbolo <- representa o pertence, , da teoria dos conjuntos). Pode-se combinar geradores numa mesma list comprehension.
A segunda funcionalidade é a sequência aritmética, que permite construir listas sob forma de intervalos. Por exemplo, o código [2..10]
cria uma lista de inteiros de 2 a 10. Pode-se omitir o fim do intervalo; [2..]
gera uma lista infinita de inteiros a partir de 2.
Há três funções primordiais sobre listas em Haskell, das quais outras funções podem ser combinadas.[14] A primeira é foldl
, que adiciona um operador dado entre cada elemento da lista, retornando o resultado da expressão gerada. Para concatenar uma lista de cadeias de caracteres cadeia = ["Uma", " ", "cadeia"]
pode-se usar foldr1 (++) cadeia
. A segunda é map
, que executa uma função a todos os elementos da lista, retornando uma nova lista. A terceira é filter
, que filtra a lista a partir de um predicado.
Tipos de dado
[editar | editar código-fonte]A tipagem de Haskell é forte. Cada expressão possui um tipo, e é possível obtê-lo em tempo de compilação através de inferência de tipo. Os tipos básicos da linguagem incluem:
Tipo de dado | Descrição | Classes | Exemplo da sintaxe |
---|---|---|---|
Bool |
Enumeração de valores boolianos, que permitem certas operações lógicas, como conjunção (&& ), disjunção (|| ) e negação (not ). |
Read, Show, Eq, Ord, Enum, Bounded | True False
|
Char |
Enumeração de caracteres 16-bit, Unicode. A faixa dos primeiro 128 caracteres é idêntica ao ASCII. | Read, Show, Eq, Ord, Enum, and Bounded | 'a'
|
Double |
Ponto flutuante com maior intervalo e precisão que Float |
RealFloat | |
Either |
Eq, Ord, Read, Show | ||
Float |
Ponto flutuante | RealFloat | 6553.612 321.6e-3 |
IO |
Tipo abstrato para operações de E/S, como putStr , print , getChar , getLine e readIO . |
Monad, Functor | |
IOError |
Tipo abstrato para erros nas operações de E/S com IO . |
Show, Eq | |
Int |
Inteiro que cobre, pelo menos, o intervalo de valores [-2^29, 2^29 - 1]. | Integral | 123
|
Integer |
Inteiro de precisão ilimitada, com as mesmas funções e operadores de Int |
Integral | 123
|
Maybe |
Lida com valores opcionais ou ilegais sem terminar o programa e sem usar o IOError de IO . |
Eq, Ord, Read, Show | |
Ordering |
Eq, Ord, Bounded, Enum, Read, Show | ||
String |
Cadeia de caracteres, representada sob forma de lista de Char . A sintaxe tanto pode ser de lista quanto a abreviação, entre aspas. |
"Texto" ['T','e','x','t','o']
| |
Tuplas | Tipo de dado algébrico de definição de registros heterogêneos, tuplas. A quantidade máxima de elementos depende da implementação, mas a quantidade mínima de quinze elementos é sempre garantida.[15] | Eq, Ord, Bounded, Read, Show | ('A',11,True)
|
Listas | Tipo de dado algébrico de definição de registros homogêneos listas. Entre os operadores disponíveis encontra-se !! , que retorna o n-ésimo elemento da lista, e ++ , que concatena duas listas distintas de mesmo tipo. Relacionado a concatenação, há o operador : , que adiciona um elemento no topo de uma lista. |
Eq, Ord | [1,2,3,4] [1..4] (1:(2:(3:(4:[]))))
|
A linguagem ainda define diversas classes padrão:
Tipo de dado | Descrição | Prove |
---|---|---|
Bounded |
Delimita um tipo de dado | |
Enum |
Provê operações em tipo sequencialmente ordenados. | succ , pred , toEnum , enumFrom
|
Eq |
Provê operadores de igualdade. | == , /=
|
Floating |
||
Fractional |
||
Functor |
Usado por tipos que podem ser mapeados. | |
Integral |
||
Ord |
Provê operadores de ordenação. | ⇐ , < , >= , >
|
Monad |
Provê operações sobre mônadas. | |
MonadPlus |
||
Num |
||
Read |
||
Real |
||
RealFloat |
||
RealFrac |
||
Show |
Operadores
[editar | editar código-fonte]Além dos operadores específicos de certos tipos de dado supracitados, vale notar também alguns outros. O operador .
realiza a composição de funções. Por exemplo, a expressão ((2+).(3*).(4-)) 2
retorna 8
, e significa .
A potenciação pode ser feita através do operador **
. Entretanto estão disponíveis também duas versões mais eficientes. Para ^^
, o expoente deve ser um inteiro; para ^
, o expoente deve ser um inteiro não negativo.
Paradigma
[editar | editar código-fonte]Paradigma funcional enfatiza o processo de identificar blocos e partes repetidas de código e constroem funções que encapsulam a funcionalidade dentro de uma simples definição. Isto aumenta a confiabilidade (não ocorrem erros de tipagem). Um programa desenvolvido nesse paradigma é, por si só, uma função, que toma como entrada os argumentos passados pelo usuário, e lhe retorna alguma saída (resultado), possivelmente utilizando-se de outras funções. O paradigma de programação funcional enxerga todos os subprogramas como funções que recebem argumentos e retornam soluções simples. A solução retornada é baseada inteiramente na entrada e o tempo em que uma função é chamada é irrelevante sendo possível a passagem de uma função como parâmetro. O programa passa a ser uma lista de funções, sendo o próprio programa principal uma lista.
Visão critica do paradigma funcional
[editar | editar código-fonte]Vantagens
[editar | editar código-fonte]- Construção eficiente de programas: a construção rápida de programas impulsiona o caráter da aprendizagem e da prototipação de programas complexos.
- Um alto nível de abstração, especialmente quando as funções são utilizadas, suprimindo muitos detalhes da programação e minimizando a probabilidade da ocorrência de muitas classes de erros
- A não dependência das operações de atribuição permite aos programas avaliações nas mais diferentes ordens. Esta característica de avaliação independente da ordem torna as linguagens funcionais as mais indicadas para a programação de computadores maciçamente paralelos.
- A ausência de operações de atribuição torna os programas funcionais muito mais simples para provas e análises matemáticas do que os programas procedurais.
Desvantagens
[editar | editar código-fonte]- Problemas que envolvam muitas variáveis (ex. banco de dados) ou muitas atividades sequenciais, essas são muitas vezes mais fáceis de se trabalhar com programas procedurais ou programas orientados a objeto.
- Implementações ineficientes: considerando que as funções têm um caráter recursivo em suas definições, invariavelmente estas tendem a ser mais ineficientes computacionalmente que as linguagens imperativas, pois tem maior chance de ocorrer erros e possuem um grande uso de memória.
Aplicações
[editar | editar código-fonte]Os pontos fortes da linguagem Haskell têm sido bem aplicados em alguns projetos. É cada vez mais utilizada em aplicações comerciais.[16] O compilador e interpretador Pugs criado por Audrey Tang é uma versão completa da linguagem Perl 6. Darcs é um sistema de controle de versões baseado em mudanças (change-based) com várias características inovadoras. A Linspire GNU / Linux escolheu Haskell para desenvolvimento das ferramentas do sistema .[17] Xmonad é um gerenciador de janelas "tile-based" para o X Window System escrito inteiramente em Haskell. Bluespec SystemVerilog é uma linguagem feita como uma extensão do Haskell.
- Darcs é um sistema de controle de revisão escrito em Haskell, com vários atributos inovadores, como mais precisão no controle de patches.
- Cabal é uma ferramenta para a construção e empacotamento das bibliotecas e programas em Haskell.
- Linspire GNU/Linux escolheu Haskell para o desenvolvimento de ferramentas de sistema.
- Xmonad é um administrador de janelas para o X Window System, escrito completamente em Haskell.
- Git-annex é uma ferramenta para administrar (grandes) arquivos de dado sob o controle de versão do Git. Provém também um sistema distribuído de sincronização de arquivo (assistente do git-annex).
- GHC é geralmente utilizado como teste para funções avançadas de programação funcional e otimização em outras linguagens de programação.
- Pandoc é uma ferramenta de conversão de formato de marcação em outra.
- O sistema de compilação The Shake aspira em ser confiável, robusto e rápido.
- ShellCheck – uma ferramenta de análise estática de shell script.
Indústria
[editar | editar código-fonte]- Facebook implementa seus programas anti-spam em Haskell, como um software de código aberto.
- Swift Navigation, um fabricante de GPS de alta precisão, implementa porções significantes de seus produtos em Haskell, gerando alguns softwares de código aberto.
- Bluespec SystemVerilog (BSV) é uma linguagem para design de semicondutores que possui uma extensão em Haskell. Além disso, as ferramentas da Bluespec Inc. são implementadas em Haskell.
- Cryptol, uma linguagem e ferramenta para desenvolver e verificar algoritmos de criptografia, é implementada em Haskell.
- seL4, o primeiro microkernel formalmente verificado, usou Haskell como protótipo de linguagem para o desenvolvedor de SO. Ao mesmo tempo, o código em Haskell definiu uma especificação executável para a tradução automática pela ferramenta de demonstração de teoremas. O código em Haskell serviu também como um protótipo intermediário antes do refinamento final de C.
Web
[editar | editar código-fonte]Frameworks de web em Haskell existem, incluindo:
- Yesod
- Snap
- Miso
Exemplos
[editar | editar código-fonte]O difundido caso do Programa Olá Mundo pode ser exemplificado em Haskell da seguinte forma:
olamundo :: IO()
olamundo = putStrLn "Olá, Mundo!"
A clássica definição da função fatorial:
fatorial :: Integer -> Integer
fatorial 0 = 1
fatorial n | n > 0 = n * fatorial (n-1)
Ou em uma linha:
fatorial n = if n > 0 then n * fatorial (n-1) else 1
Este artigo descreve o fatorial como uma função recursiva, terminando com um caso que serve como base. É semelhante ao encontrado nas descrições de fatoriais em livros didáticos de matemática. Grande parte do código Haskell é semelhante ao padrão da notação matemática na potencialidade expressiva e na sintaxe. A primeira linha da função fatorial descreve os tipos desta função; embora seja opcional, é considerado bom estilo[18] incluí-la. Ela pode ser lida como a função fatorial (fatorial) tem tipo (::) inteiro para inteiro (Integer -> Integer). Ou seja, ele tem um inteiro como um argumento e retorna outro inteiro. O tipo de uma definição é inferido automaticamente se o programador não forneceu uma notação de tipo.
A segunda linha depende de um casamento de padrões (pattern matching), uma característica importante do Haskell. Note que os parâmetros da função são separados por parênteses e não por espaços. Quando o argumento da função é 0 (zero) será devolvido o inteiro 1 (um). Para todos os outros casos, a terceira linha é tentada. Esta é a recursividade, e executa a função novamente até que um caso que sirva como base seja atingido.
Um "guard" protege a terceira linha de números negativos, sendo que um fatorial não permite números negativos, indefinido-o. Sem um "guard" essa função seria recursiva "fatorando" todos os números negativos, sem nunca chegar à base 0. Se um inteiro negativo é passado para o fatorial funcionar como um argumento, o programa irá falhar com um erro "runtime". De último caso, poderia ser tratada esta condição de erro e imprimir uma mensagem de erro adequada em seu lugar.
A descrição acima é parecida com as descrições matemática, tais como definições de uma função e não como uma atribuição de um valor numérico para uma variável.
Uma outra definição da função fatorial (usando uma notação de lista em Haskell e a função padrão product
):
fatorial n = product [1..n]
A mesma função mas agora no estilo point-free. Repare-se que os argumentos desaparecem (o ponto significa composição de funções):
fatorial = product . enumFromTo 1
Uma implementação da função que retorna o n-ésimo termo na seqüência de Fibonacci:
fib 0 = 0
fib 1 = 1
fib n = fib (n - 2) + fib (n - 1)
Uma função que retorna uma lista dos números de Fibonacci:
fibs@(_:rest) = 0 : 1 : (zipWith (+) fibs rest)
A função anterior cria uma lista infinita, que é possível graças a avaliação preguiçosa.
Poderia-se implementar fib
como:
fib n = fibs !! n
O algoritmo quicksort pode ser elegantemente escrito em Haskell:
qsort [] = []
qsort (h:t) = qsort menores_que_h ++ [h] ++ qsort maiores_que_h
where
menores_que_h = [x | x <- t, x < h]
maiores_que_h = [x | x <- t, x >= h]
Uma forma mais compacta desse mesmo algoritmo seria:
quicksort [] = []
quicksort (s:xs) = quicksort [x|x <- xs,x < s] ++ [s] ++ quicksort [x|x <- xs,x >= s]
- Nota: Por causa das excessivas cópias e concatenações de listas, este código pode ser lento.
Implementações
[editar | editar código-fonte]As seguintes implementações estão totalmente, ou quase, de acordo com o padrão Haskell 98. Todas são distribuídas sob licenças código aberto.
- GHC. O Glasgow Haskell Compiler gera código nativo de diferentes arquitecturas e pode também gerar código C. Ele é provavelmente o mais popular compilador Haskell, e algumas bibliotecas (como bindings para OpenGL) funcionam apenas com ele.
- Hugs é um interpretador de bytecode. Oferece rápida compilação dos programas e razoável velocidade de execução. Também dispõe de uma simples biblioteca gráfica. Hugs é ideal para pessoas que estão aprendendo os básicos de Haskell. É a mais portável e leve das implementações de Haskell.
- nhc98[19] é outro compilador que gera bytecode. O bytecode resultante executa significativamente mais rápido do que o equivalente do Hugs. Nhc98 foca na minimização do uso de memória, e é uma boa escolha para máquinas velhas/lentas.
- HBC é outro compilador Haskell para código nativo. Seu desenvolvimento não está ativo, mas ele é funcional.
- Helium[20] é um novo dialeto do Haskell. O foco é na facilidade de aprendizado. Atualmente carece de typeclasses, tornando-o incompatível com muitos programas Haskell.
Crítica
[editar | editar código-fonte]Jan-Wilem Maessen, em 2002, e Simon Peyton Jones, em 2003, discutiram problemas relacionados à avaliação preguiçosa, enquanto estudavam motivos teóricos para isso. Além de considerações práticas como melhor performance, eles perceberam que, além da sobrecarga de desempenho, a avaliação preguiçosa deixava mais difícil para os programadores considerarem o desempenho do código (particularmente o uso de espaço).
Bastiaan Heeren, Daan Leijen e Arjan van IJzendoorn em 2003, observaram alguns obstáculos para quem quer aprender Haskell: “ a sutil sintaxe e o sofisticado sistema de tipos de Haskell são uma faca de 2 gumes – extremamente apreciada por programadores experientes, mas também uma fonte de frustação entre iniciantes, já que em geral a linguagem Haskell leva a mensagens de erro enigmáticas”. Para resolver isso, pesquisadores da Universidade de Utrecht desenvolveram um interpretador moderno chamado de Helium, que facilitou o entendimento das mensagens de erro limitando a generalidade de algumas funções, em particular remover o suporte para classes.
Bem Lippmeier criou o Disciple como um dialeto estrito por padrão (preguiçosa por notação explícita) de Haskell com um sistema de tipo e efeito para resolver dificuldades da avaliação preguiçosa e em usar estruturas de dados tradicionais como arrays mutáveis. Ele discute que “atualizações destrutivas fornecem ao programador 2 ferramentas importantes e poderosas [...] um conjunto de estruturas de dados eficientes parecidos com array para administrar coleções de objetos, e [...] a habilidade de transmitir um novo valor para todas as partes do programa com carga mínima no programador”.
Robert Harper, um dos autores do Standard ML, deu razões para não usar Haskell como linguagem para programação introdutória. Entre essas razões estão: a dificuldade de discorrer sobre recursos com avaliação não estrita, a avaliação preguiçosa complica a definição de tipos de dados e raciocínio induzido e a “inferioridade” do (antigo) sistema de classe do Haskell comparado com o sistema de módulos do ML.
Foi constantemente criticado por desenvolvedores por causa da falta de boa administração de diferentes versões da mesma biblioteca pela ferramenta padrão de construção, Cabal. Foi resolvido pelo lançamento do Stack, que administra o Cabal, para fazer o trabalho na construção.
Linguagens relacionadas
[editar | editar código-fonte]Clean é um relativo mais próximo e antigo do Haskell. Esse desvio se dá devido aos tipos únicos ao invés do E/S e seus efeitos colaterais.
Uma série de linguagens inspiradas pelo Haskell, mas com sistemas de diferentes tipos, foram desenvolvidas, incluindo:
- Agda, uma linguagem funcional com tipos dependentes
- Idris, uma linguagem funcional de propósito geral com tipos dependentes, desenvolvido pela Universidade de St Andrews
- Epigram, uma linguagem funcional com tipos dependentes adequada para provar propriedades de programas
- Cayenne, com tipos dependentes
- Ωmega, compilador estrito
- Elm, uma linguagem funcional para criar apps de wb em front-end
Máquina Virtual de Java (JVM) baseado em:
- Frege, uma linguagem semelhante a Haskell, com tipos escalares de Java e com boa integração a Java.
- Jaskell, uma linguagem funcional de script que roda em JVM.
- Eta-lang, que tem como intenção ser um Haskell em JVM.
Outras linguagens relacionadas incluem:
- Curry, uma linguagem funcional/lógica baseada em Haskell
Haskell serviu como teste para muitas novas ideias em design de linguagem. Houve muitas variações de Haskell produzidas, explorando novas ideias de linguagem, incluindo:
- Haskell Paralelo:
- Da Universidade de Glascow, que suporta clusters de máquinas ou multiprocessadores únicos. Além disso Haskell é suporte para o paralelismo em Multiprocessadores Simétricos.
- Do MIT
- Haskell distribuída (antigamente Goffin) e Eden.
- Haskell ansioso, baseado em avaliações especulativas.
- Versões com orientação a objetos, como Haskell++ e Mondrian.
- Haskell genérico, uma versão de Haskell com suporte de tipo de sistema para programação genérica.
- O’Haskell, uma extensão de Haskell adicionando orientação a objetos e programação concorrente.
- Disciple, um dialeto estrito por padrão de Haskell que suporta atualizações destrutivas, esforços computacionais, tipo de projeções de campos direcionados e aspectos funcionais.
- Hume, uma linguagem funcional estrita para sistemas embarcados baseados em processos como autômatos sem estados sobre um tipo de tuplas de canais de caixa de correio de um elemento onde o estado é mantido pelo feedback nas caixas de correio, e uma descrição de mapeamento de saídas para canais como cabeamento de caixa, com uma linguagem de expressão e sintaxe semelhantes a Haskell.
Leitura adicional
[editar | editar código-fonte]- Página do livro: Haskell: Uma Abordagem Prática, um livro de nível introdutório a médio sobre a linguagem Haskell, com uma apresentação crescente as principais características da linguagem.
Ver também
[editar | editar código-fonte]Referências
- ↑ Sítio de Paul Hudak
- ↑ Curry, Haskell (1934), «Functionality in Combinatory Logic», Proceedings of the National Academy of Sciences, 20, pp. 584–590
- ↑ Curry, Haskell B.; Feys, Robert; Craig, William (1958), Combinatory Logic Vol. I, Amsterdam: North-Holland, with 2 sections by William Craig, see paragraph 9E
- ↑ De Bruijn, Nicolaas (1968), Automath, a language for mathematics, Department of Mathematics, Eindhoven University of Technology, TH-report 68-WSK-05. Reprinted in revised form, with two pages commentary, in: Automation and Reasoning, vol 2, Classical papers on computational logic 1967-1970, Springer Verlag, 1983, pp. 159-200.
- ↑ Howard, William A. (1980) [original paper manuscript from 1969], «The formulae-as-types notion of construction», in: Seldin, Jonathan P.; Hindley, J. Roger, To H.B. Curry: Essays on Combinatory Logic, Lambda Calculus and Formalism, ISBN 978-0-12-349050-6, Boston, MA: Academic Press, pp. 479–490.
- ↑ Hudak 2007, p. 2
- ↑ Hudak 2007, p. 3
- ↑ «Preface». Haskell 98 Language and Libraries: The Revised Report (em inglês). Sítio oficial. Dezembro de 2002. Consultado em 29 de setembro de 2008
- ↑ «The History of Haskell» (em inglês). Sítio oficial. Consultado em 29 de setembro de 2008. Arquivado do original em 29 de abril de 2009
- ↑ Hudak 2007, p. 5
- ↑ Simon Peyton Jones (dezembro de 2002). «Haskell 98 Language and Libraries: The Revised Report» (em inglês). Sítio oficial. Consultado em 29 de setembro de 2008
- ↑ «Future development of Haskell» (em inglês). Sítio oficial. Consultado em 29 de setembro de 2008
- ↑ Hudak 2007, p. 8
- ↑ Du Bois
- ↑ The Haskell 98 Report, s. 6.1.4
- ↑ «Haskell in Industry»
- ↑ «Linspire/Freespire Core OS Team and Haskell». Debian Haskell mailing list. Maio de 2006
- ↑ HaskellWiki: Type signatures as good style
- ↑ «nhc98». www.cs.york.ac.uk. Consultado em 1 de maio de 2011
- ↑ «WebHome < Helium < TWiki». www.cs.uu.nl. Consultado em 1 de maio de 2011
Referências bibliográficas
[editar | editar código-fonte]- Naomi Hamilton (19 de setembro de 2008). «The A-Z of Programming Languages: Haskell» (em inglês). Computerworld. Consultado em 29 de setembro de 2008. Arquivado do original em 17 de setembro de 2008
- Paul Hudak, John Hughes, Simon Peyton Jones, Philip Wadler (16 de abril de 2007). «A History of Haskell: Being Lazy With Class» (PDF) (em inglês). Third ACM SIGPLAN History of Programming Languages Conference (HOPL-III). Consultado em 29 de setembro de 2008
- André Rauber Du Bois. «Programação Funcional com a Linguagem Haskell» (PDF) (em inglês). Universidade de Heriot-Watt. Consultado em 30 de setembro de 2008. Arquivado do original (PDF) em 25 de novembro de 2006
- «The Haskell 98 Report: Predefined Types and Classes» (em inglês). Sítio oficial. Dezembro de 2002. Consultado em 30 de setembro de 2008
Ligações externas
[editar | editar código-fonte]- Sítio oficial
- «Introdução ao Haskell 98» (PDF) (em inglês)
- «Outros exemplos de códigos em Haskell» (em inglês)