Haskell (linguagem de programação) - Haskell (programming language)

Haskell
Logo de Haskell
Paradigma Puramente funcional
Projetado por Lennart Augustsson , Dave Barton, Brian Boutel, Warren Burton, Joseph Fasel, Kevin Hammond, Ralf Hinze, Paul Hudak , John Hughes , Thomas Johnsson, Mark Jones, Simon Peyton Jones , John Launchbury , Erik Meijer , John Peterson, Alastair Reid, Colin Runciman, Philip Wadler
Apareceu pela primeira vez 1990 ; 31 anos atrás ( 1990 )
Versão estável
Haskell 2010 / julho 2010 ; 11 anos atrás ( 2010-07 )
Versão de visualização
Haskell 2020 anunciado
Disciplina de digitação Inferido , estático , forte
SO Plataforma cruzada
Extensões de nome de arquivo .hs, .lhs
Local na rede Internet www .haskell .org
Implementações principais
GHC , Abraços , NHC, JHC, Yhc , UHC
Dialetos
Hélio , Gofer
Influenciado por
Clean , FP , Gofer , Hope e Hope + , Id , ISWIM , KRC , Lisp , Miranda , ML e Standard ML , Orwell , SASL , Scheme , SISAL
Influenciado
Agda , Bluespec , C ++ 11 / Concepts , C # / LINQ , CAL, Cayenne , Clean , Clojure , CoffeeScript , Curry , Elm , Epigram , Escher , F # , Frege , Hack , Idris , Isabelle , Java / Generics , LiveScript , Mercury , Ωmega , PureScript , Python , Raku , Rust , Scala , Swift , Timber , Visual Basic 9.0

Haskell ( / h æ s k əl / ) é um de uso geral , de tipagem estática , puramente funcional linguagem de programação com a inferência de tipos e avaliação preguiçosa . Projetado para ensino, pesquisa e aplicação industrial, Haskell foi pioneiro em uma série de recursos avançados de linguagem de programação, como classes de tipo , que permitem a sobrecarga do operador com segurança de tipo . A principal implementação de Haskell é o Glasgow Haskell Compiler (GHC). Recebeu o nome do lógico Haskell Curry .

A semântica de Haskell é historicamente baseada na linguagem de programação Miranda , que serviu para concentrar os esforços do grupo de trabalho inicial de Haskell. A última especificação formal da linguagem foi feita em julho de 2010, enquanto o desenvolvimento do GHC expandiu Haskell por meio de extensões de linguagem. A próxima especificação formal foi planejada para 2020.

Haskell é usado na academia e na indústria. Em maio de 2021, Haskell era a 28ª linguagem de programação mais popular em termos de pesquisas do Google por tutoriais e representava menos de 1% dos usuários ativos no repositório de código-fonte do GitHub.

História

Após o lançamento do Miranda pela Research Software Ltd. em 1985, o interesse por linguagens funcionais preguiçosas cresceu. Em 1987, existia mais de uma dúzia de linguagens de programação puramente funcionais e não estritas . Miranda era o mais usado, mas era um software proprietário . Na conferência sobre Linguagens de Programação Funcional e Arquitetura de Computadores (FPCA '87) em Portland, Oregon , houve um forte consenso de que um comitê seja formado para definir um padrão aberto para tais linguagens. O objetivo do comitê era consolidar as linguagens funcionais existentes em uma linguagem comum para servir de base para pesquisas futuras em design de linguagens funcionais.

Haskell 1.0 a 1.4

As classes de tipo , que permitem a sobrecarga do operador com segurança de tipo , foram propostas pela primeira vez por Philip Wadler e Stephen Blott para o ML padrão, mas foram implementadas pela primeira vez em Haskell entre 1987 e a versão 1.0.

A primeira versão de Haskell ("Haskell 1.0") foi definida em 1990. Os esforços do comitê resultaram em uma série de definições de linguagem (1.0, 1.1, 1.2, 1.3, 1.4).

Hierarquia de classes de tipo no prelúdio de Haskell a partir do GHC 7.10. A inclusão de Foldable e Traversable (com alterações correspondentes nas assinaturas de tipo de algumas funções), e de Applicative como intermediário entre Functor e Monad, são desvios do padrão Haskell 2010.

Haskell 98

No final de 1997, a série culminou em Haskell 98 , com o objetivo de especificar uma versão estável, mínima e portátil da linguagem e uma biblioteca padrão de acompanhamento para o ensino, e como base para futuras extensões. O comitê deu as boas-vindas expressamente à criação de extensões e variantes do Haskell 98 por meio da adição e incorporação de recursos experimentais.

Em fevereiro de 1999, o padrão de linguagem Haskell 98 foi publicado originalmente como 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 continua a evoluir rapidamente, com a implementação do Glasgow Haskell Compiler (GHC) representando o padrão atual de fato .

Haskell 2010

No início de 2006, o processo de definição de um sucessor para o padrão Haskell 98, informalmente denominado Haskell Prime , começou. Pretendia-se que fosse um processo contínuo e incremental de revisão da definição do idioma, produzindo uma nova revisão até uma vez por ano. A primeira revisão, denominada Haskell 2010 , foi anunciada em novembro de 2009 e publicada em julho de 2010.

Haskell 2010 é uma atualização incremental da linguagem, incorporando principalmente vários recursos bem usados ​​e incontroversos habilitados anteriormente por meio de sinalizadores específicos do compilador.

  • Nomes de módulos hierárquicos. Os nomes dos módulos podem consistir em sequências separadas por pontos de identificadores em maiúsculas, em vez de apenas um desses identificadores. Isso permite que os módulos sejam nomeados de maneira hierárquica (por exemplo, em Data.Listvez de List), embora tecnicamente os módulos ainda estejam em um único namespace monolítico. Esta extensão foi especificada em um adendo ao Haskell 98 e foi, na prática, universalmente usada.
  • A interface de função estrangeira (FFI) permite ligações a outras linguagens de programação. Apenas as ligações para C são especificadas no Relatório, mas o design permite outras ligações de linguagem. Para oferecer suporte a isso, as declarações de tipo de dados não podiam conter construtores, permitindo tipos nonce robustos para dados externos que não podiam ser construídos em Haskell. Essa extensão também foi especificada anteriormente em um Adendo ao Relatório Haskell 98 e amplamente utilizada.
  • Os chamados padrões n + k (definições da forma fact (n+1) = (n+1) * fact n) não eram mais permitidos. Esse açúcar sintático tinha uma semântica enganosa, em que o código parecia usar o (+)operador, mas na verdade foi alterado para codificar usando (-)e (>=).
  • As regras de inferência de tipo foram relaxadas para permitir que mais programas façam a verificação de tipo.
  • Alguns problemas de sintaxe (mudanças na gramática formal) foram corrigidos: guardas de padrão foram adicionados, permitindo a correspondência de padrões dentro de guardas; a resolução da fixidez do operador foi especificada de uma maneira mais simples que refletia a prática real; um caso extremo na interação da sintaxe lexical de operadores e comentários da linguagem foi abordado, e a interação de notação de doação e if-then-else foi ajustada para eliminar erros de sintaxe inesperados.
  • O LANGUAGE pragma foi especificado. Em 2010, dezenas de extensões para a linguagem estavam em amplo uso, e o GHC (entre outros compiladores) forneceu o LANGUAGEpragma para especificar extensões individuais com uma lista de identificadores. Os compiladores Haskell 2010 são necessários para oferecer suporte à Haskell2010extensão e são incentivados a oferecer suporte a várias outras, que correspondem às extensões adicionadas no Haskell 2010.

Recursos

Haskell apresenta avaliação preguiçosa , expressões lambda , correspondência de padrões , compreensão de lista , classes de tipo e polimorfismo de tipo . É uma linguagem puramente funcional , o que significa que as funções geralmente não têm efeitos colaterais . Existe uma construção distinta para representar os efeitos colaterais ortogonais ao tipo de funções. Uma função pura pode retornar um efeito colateral que é subsequentemente executado, modelando as funções impuras de outras linguagens.

Haskell tem um forte , estática tipo de sistema baseado em Hindley-Milner inferência de tipos . Sua principal inovação nesta área são as classes de tipos, originalmente concebidas como uma forma de princípio de adicionar sobrecarga à linguagem, mas desde que encontraram muitos outros usos.

A construção que representa os efeitos colaterais é um exemplo de mônada : uma estrutura geral que pode modelar vários cálculos, como tratamento de erros, não-determinismo , análise e memória transacional de software . Eles são definidos como tipos de dados comuns, mas Haskell fornece algum açúcar sintático para seu uso.

Haskell tem uma especificação aberta e publicada, e existem várias implementações . Sua implementação principal, o Glasgow Haskell Compiler (GHC), é um interpretador e um compilador de código nativo que roda na maioria das plataformas. GHC é conhecido por seu rico sistema de tipos que incorpora inovações recentes, como tipos de dados algébricos generalizados e famílias de tipos. O Computer Language Benchmarks Game também destaca sua implementação de alto desempenho de simultaneidade e paralelismo .

Uma comunidade ativa e crescente existe em torno do idioma, e mais de 5.400 bibliotecas e ferramentas de código aberto de terceiros estão disponíveis no repositório de pacotes online Hackage .

Exemplos de código

Um "Olá, mundo!" programa em Haskell (apenas a última linha é estritamente necessária):

module Main (main) where          -- not needed in interpreter, is the default in a module file

main :: IO ()                     -- the compiler can infer this type definition
main = putStrLn "Hello, World!"

A função fatorial em Haskell, definida de algumas maneiras diferentes:

-- [[Type signature|Type annotation]] (optional, same for each implementation)
factorial :: (Integral a) => a -> a

-- Using recursion (with the "ifthenelse" expression)
factorial n = if n < 2
              then 1
              else n * factorial (n - 1)

-- Using recursion (with pattern matching)
factorial 0 = 1
factorial n = n * factorial (n - 1)

-- Using recursion (with guards)
factorial n
   | n < 2     = 1
   | otherwise = n * factorial (n - 1)

-- Using a list and the "product" function
factorial n = product [1..n]

-- Using fold (implements "product")
factorial n = foldl (*) 1 [1..n]

-- Point-free style
factorial = foldr (*) 1 . enumFromTo 1

Como o tipo Integer tem precisão arbitrária , este código computará valores como factorial 100000(um número de 456.574 dígitos), sem perda de precisão.

Uma implementação de um algoritmo semelhante à classificação rápida em listas, em que o primeiro elemento é considerado o pivô:

-- Type annotation (optional, same for each implementation)
quickSort :: Ord a => [a] -> [a]

-- Using list comprehensions
quickSort []     = []                               -- The empty list is already sorted
quickSort (x:xs) = quickSort [a | a <- xs, a < x]   -- Sort the left part of the list
                   ++ [x] ++                        -- Insert pivot between two sorted parts
                   quickSort [a | a <- xs, a >= x]  -- Sort the right part of the list

-- Using filter
quickSort []     = []
quickSort (x:xs) = quickSort (filter (<x) xs)
                   ++ [x] ++
                   quickSort (filter (>=x) xs)

Implementações

Todas as implementações listadas são distribuídas sob licenças de código aberto .

Implementações que estão totalmente ou quase em conformidade com o padrão Haskell 98, incluem:

  • O Glasgow Haskell Compiler (GHC) compila para código nativo em muitas arquiteturas de processador diferentes e para ANSI C , por meio de uma das duas linguagens intermediárias : C-- , ou em versões mais recentes, bitcode LLVM (anteriormente Low Level Virtual Machine). GHC se tornou o dialeto Haskell padrão de fato . Existem bibliotecas (por exemplo, ligações para OpenGL ) que funcionam apenas com GHC. GHC também é distribuído com a plataforma Haskell .
  • Jhc, um compilador Haskell escrito por John Meacham, enfatiza a velocidade e a eficiência dos programas gerados e a exploração de novas transformações de programa.
    • Ajhc é um fork de Jhc.
  • O Compilador Utrecht Haskell (UHC) é uma implementação Haskell da Universidade de Utrecht . Ele suporta quase todos os recursos do Haskell 98, além de muitas extensões experimentais. Ele é implementado usando gramáticas de atributos e atualmente é usado principalmente para pesquisas em sistemas de tipos gerados e extensões de linguagem.

As implementações que não são mais mantidas ativamente incluem:

  • O sistema Gofer do usuário Haskell ( Hugs ) é um interpretador de bytecode . Ele já foi uma das implementações mais amplamente usadas, junto com o compilador GHC, mas agora foi substituído principalmente pelo GHCi. Ele também vem com uma biblioteca de gráficos.
  • HBC é uma implementação inicial de suporte a Haskell 1.4. Ele foi implementado por Lennart Augustsson e baseado no Lazy ML . Ele não foi desenvolvido ativamente por algum tempo.
  • nhc98 é um compilador de bytecode com foco em minimizar o uso de memória.
    • O York Haskell Compiler ( Yhc ) foi um fork do nhc98, com o objetivo de ser mais simples, mais portátil e eficiente e integrar o suporte para Hat, o rastreador Haskell. Ele também tinha um back-end JavaScript , permitindo aos usuários executar programas Haskell em navegadores da web .

As implementações que não são totalmente compatíveis com Haskell 98 e que usam uma variante da linguagem Haskell incluem:

  • Eta e Frege são dialetos de Haskell direcionados à Java Virtual Machine .
  • Gofer era um dialeto educacional de Haskell, com um recurso chamado classes de construtor , desenvolvido por Mark Jones. Foi suplantado por Hugs (Sistema Gofer do usuário de Haskell).
  • Hélio, um dialeto mais recente de Haskell. O foco é tornar o aprendizado mais fácil por meio de mensagens de erro mais claras. Atualmente não tem suporte completo para classes de tipo, tornando-o incompatível com muitos programas Haskell.

Aplicativos notáveis

  • O assistente de prova Agda está escrito em Haskell.
  • Cabal é uma ferramenta para construir e empacotar bibliotecas e programas Haskell.
  • Darcs é um sistema de controle de revisão escrito em Haskell, com diversos recursos inovadores, como um controle mais preciso dos patches a serem aplicados.
  • GHC também é frequentemente um testbed para recursos de programação funcional avançados e otimizações em outras linguagens de programação.
  • Git-attachment é uma ferramenta para gerenciar (big) arquivos de dados sob controle de versão Git . Ele também fornece um sistema de sincronização de arquivos distribuído (assistente git-attachment).
  • Linspire Linux escolheu Haskell para o desenvolvimento de ferramentas de sistema.
  • Pandoc é uma ferramenta para converter um formato de marcação em outro.
  • Pugs é um compilador e interpretador da linguagem de programação Raku (anteriormente Perl 6).
  • Xmonad é um gerenciador de janelas para o X Window System , escrito totalmente em Haskell.

Indústria

  • Bluespec SystemVerilog (BSV) é uma linguagem para projeto de semicondutores que é uma extensão de Haskell. Além disso, as ferramentas da Bluespec, Inc. são implementadas em Haskell.
  • Cryptol , uma linguagem e uma cadeia de ferramentas para desenvolver e verificar algoritmos de criptografia , é implementado em Haskell.
  • O Facebook implementa seus programas anti-spam em Haskell, mantendo a biblioteca de acesso a dados subjacente como software de código aberto .
  • A plataforma de blockchain Cardano é implementada em Haskell.
  • O GitHub implementou a Semantic , uma biblioteca de código aberto para análise, comparação e interpretação de código-fonte não confiável, em Haskell.
  • seL4 , o primeiro microkernel formalmente verificado , usou Haskell como uma linguagem de prototipagem para o desenvolvedor de SO. Ao mesmo tempo, o código Haskell definiu uma especificação executável com a qual raciocinar, para tradução automática pela ferramenta de prova de teorema. O código Haskell, portanto, serviu como um protótipo intermediário antes do refinamento C final .

Rede

Estruturas web notáveis escritas para Haskell incluem:

Crítica

Jan-Willem Maessen, em 2002, e Simon Peyton Jones , em 2003, discutiram os problemas associados à avaliação preguiçosa, ao mesmo tempo que reconheciam os motivos teóricos para ela. Além de considerações puramente práticas, como desempenho aprimorado, eles observam que, além de adicionar alguma sobrecarga de desempenho, a avaliação preguiçosa torna mais difícil para os programadores raciocinar sobre o desempenho de seu código (particularmente o uso de espaço).

Bastiaan Heeren, Daan Leijen e Arjan van IJzendoorn em 2003 também observaram alguns obstáculos para os alunos de Haskell: "A sintaxe sutil e o sofisticado sistema de tipos de Haskell são uma faca de dois gumes - altamente apreciada por programadores experientes, mas também uma fonte de frustração entre os iniciantes , uma vez que a generalidade de Haskell freqüentemente leva a mensagens de erro enigmáticas. " Para resolver isso, pesquisadores da Universidade de Utrecht desenvolveram um intérprete avançado chamado Helium , que melhorou a facilidade de uso das mensagens de erro, limitando a generalidade de alguns recursos do Haskell e, em particular, removendo o suporte para classes de tipo .

Ben Lippmeier projetou Disciple como um dialeto estrito por padrão (preguiçoso por anotação explícita) de Haskell com um sistema de tipo e efeito, para lidar com as dificuldades de Haskell em raciocinar sobre avaliação preguiçosa e no uso de estruturas de dados tradicionais, como matrizes mutáveis. Ele argumenta (p. 20) que "a atualização destrutiva fornece ao programador duas ferramentas importantes e poderosas ... um conjunto de estruturas de dados semelhantes a matrizes eficientes para gerenciar coleções de objetos e ... a capacidade de transmitir um novo valor para todas as partes de um programa com carga mínima para o programador. "

Robert Harper , um dos autores do Standard ML , deu suas razões para não usar Haskell para ensinar programação introdutória. Entre eles estão a dificuldade de raciocinar sobre o uso de recursos com avaliação não estrita, que a avaliação preguiçosa complica a definição de tipos de dados e raciocínio indutivo e a "inferioridade" do (antigo) sistema de classes de Haskell em comparação com o sistema de módulos do ML.

A ferramenta de construção de Haskell, Cabal , tem sido historicamente criticada por lidar mal com várias versões da mesma biblioteca, um problema conhecido como "inferno Cabal". O servidor Stackage e a ferramenta de construção Stack foram feitos em resposta a essas críticas. O próprio Cabal agora tem um sistema de construção muito mais sofisticado, fortemente inspirado no Nix , que se tornou o padrão com a versão 3.0.

Linguagens relacionadas

Clean é um parente próximo e um pouco mais velho de Haskell. Seu maior desvio de Haskell está no uso de tipos de exclusividade em vez de mônadas para E / S e efeitos colaterais.

Uma série de linguagens inspiradas em Haskell, mas com sistemas de tipos diferentes, foram desenvolvidas, incluindo:

Outros idiomas relacionados incluem:

  • Curry , uma linguagem de programação funcional / lógica baseada em Haskell.

Variantes notáveis ​​de Haskell incluem:

  • Haskell genérico , uma versão do Haskell com suporte ao sistema de tipos para programação genérica .
  • Hume , uma linguagem funcional estrita para sistemas embarcados com base em processos como autômatos sem estado sobre uma espécie de tuplas de canais de caixa de correio de um elemento onde o estado é mantido por feedback nas caixas de correio e uma descrição de mapeamento de saídas para canais como fiação de caixa, com um Linguagem e sintaxe de expressão semelhante a Haskell.

Conferências e workshops

A comunidade Haskell se reúne regularmente para atividades de pesquisa e desenvolvimento. Os principais eventos são:

A partir de 2006, ocorreu uma série de hackathons organizados , a série Hac, com o objetivo de aprimorar as ferramentas e bibliotecas de linguagens de programação.

Referências

Leitura adicional

Relatórios
Livros didáticos
Tutoriais
História

links externos