Compilador Glasgow Haskell - Glasgow Haskell Compiler

Compilador Glasgow Haskell
Autor (es) original (is) Kevin hammond
Desenvolvedor (s) A equipe Glasgow Haskell
lançamento inicial Dezembro de 1992 ( 1992-12 )
Versão estável
9.0.1  Edite isso no Wikidata / 4 de fevereiro de 2021 ; 7 meses atrás ( 4 de fevereiro de 2021 )
Repositório
Escrito em Haskell e C
Sistema operacional Linux , OS X 10.7 Lion e posterior, iOS , Windows 2000 e posterior, FreeBSD , Solaris 10 e posterior
Plataforma x86 , x86-64 , ARM
Disponível em inglês
Modelo Compilador
Licença Nova Licença BSD
Local na rede Internet www .haskell .org / ghc /

O Glasgow Haskell Compiler ( GHC ) é um compilador de código -fonte aberto para a linguagem de programação funcional Haskell . Ele fornece um ambiente de plataforma cruzada para a escrita e teste de código Haskell e oferece suporte a várias extensões, bibliotecas e otimizações que agilizam o processo de geração e execução de código. GHC é o compilador Haskell mais comumente usado. Os principais desenvolvedores são Simon Peyton Jones e Simon Marlow .

História

GHC originalmente começou em 1989 como um protótipo, escrito em LML (Lazy ML) por Kevin Hammond na Universidade de Glasgow . Mais tarde naquele ano, o protótipo foi totalmente reescrito em Haskell, exceto por seu analisador , por Cordelia Hall, Will Partain e Simon Peyton Jones. Seu primeiro lançamento beta foi em 1 de abril de 1991 e versões subsequentes adicionaram um analisador de rigidez , bem como extensões de linguagem, como E / S monádica , matrizes mutáveis, tipos de dados unboxed, modelos de programação simultânea e paralela (como memória transacional de software e paralelismo de dados ) e um profiler .

Peyton Jones, assim como Marlow, mais tarde mudou-se para a Microsoft Research em Cambridge, Inglaterra , onde continuaram sendo os principais responsáveis ​​pelo desenvolvimento do GHC. GHC também contém código de mais de trezentos outros contribuidores. Desde 2009, as contribuições de terceiros para o GHC foram financiadas pelo Grupo Industrial Haskell.

Arquitetura

O próprio GHC é escrito em Haskell , mas o sistema de tempo de execução para Haskell, essencial para executar programas, é escrito em C e C-- .

O front-end do GHC - incorporando o lexer , o analisador e o typechecker - é projetado para preservar o máximo possível de informações sobre o idioma de origem até que a inferência de tipo seja concluída, com o objetivo de fornecer mensagens de erro claras aos usuários. Após a verificação de tipo, o código Haskell é desugar em uma linguagem intermediária tipada conhecida como "Core" (baseada no Sistema F , estendido com expressões lete case). Núcleo foi estendido para suportar tipos de dados algébricas generalizadas no seu sistema tipo , e agora é baseado sobre a ampliação do sistema de F conhecido como Sistema F C .

Na tradição da compilação dirigida por tipo, o simplificador do GHC, ou "meio termo", onde a maioria das otimizações implementadas no GHC são realizadas, é estruturado como uma série de transformações de origem para origem no código do Core. As análises e transformações realizadas neste estágio do compilador incluem análise de demanda (uma generalização da análise de rigidez ), aplicação de regras de reescrita definidas pelo usuário (incluindo um conjunto de regras incluídas nas bibliotecas padrão do GHC que realizam fusão de dobrar / construir ), desdobramento (chamado de " inlining "em compiladores mais tradicionais), let-floating , uma análise que determina quais argumentos de função podem ser desempacotados, análise de resultado de produto construída , especialização de funções sobrecarregadas , bem como um conjunto de transformações locais mais simples, como dobramento constante e redução beta .

O backend do compilador transforma o código do Core em uma representação interna de C--, por meio de uma linguagem intermediária STG (abreviação de "Spineless Tagless G-machine"). O código C-- pode então seguir um de três caminhos: ele é impresso como código C para compilação com GCC , convertido diretamente em código de máquina nativo (a fase tradicional de " geração de código ") ou convertido em LLVM IR para compilação com LLVM . Em todos os três casos, o código nativo resultante é finalmente vinculado ao sistema de tempo de execução GHC para produzir um executável.

Língua

GHC está em conformidade com os padrões de linguagem, Haskell 98 e Haskell 2010 . Ele também suporta muitas extensões opcionais para o padrão Haskell: por exemplo, a biblioteca de memória transacional de software (STM), que permite Transações de Memória Composáveis .

Extensões para Haskell

Uma série de extensões para Haskell foram propostas. Essas extensões fornecem recursos não descritos na especificação da linguagem ou redefinem construções existentes. Como tal, cada extensão pode não ser suportada por todas as implementações de Haskell. Há um esforço contínuo para descrever as extensões e selecionar aquelas que serão incluídas nas versões futuras da especificação do idioma.

As extensões suportadas pelo Compilador Glasgow Haskell incluem:

  • Tipos e operações não encaixotados. Eles representam os tipos de dados primitivos do hardware subjacente, sem a indireção de um ponteiro para o heap ou a possibilidade de avaliação adiada. O código numericamente intensivo pode ser significativamente mais rápido quando codificado usando esses tipos.
  • A capacidade de especificar uma avaliação estrita para um valor, associação de padrão ou campo de tipo de dados.
  • Sintaxe mais conveniente para trabalhar com módulos, padrões, compreensões de lista , operadores, registros e tuplas.
  • Açúcar sintático para computação com setas e valores monádicos definidos recursivamente . Ambos os conceitos estendem a anotação do monádica fornecida no Haskell padrão.
  • Um sistema significativamente mais poderoso de tipos e typeclasses, descrito abaixo.
  • Template Haskell , um sistema para metaprogramação em tempo de compilação . Um programador pode escrever expressões que produzem código Haskell na forma de uma árvore de sintaxe abstrata . Essas expressões são verificadas no tipo e avaliadas em tempo de compilação; o código gerado é então incluído como se tivesse sido escrito diretamente pelo programador. Juntamente com a capacidade de refletir sobre as definições, isso fornece uma ferramenta poderosa para outras extensões da linguagem.
  • Quase-cotação, que permite ao usuário definir uma nova sintaxe concreta para expressões e padrões. A quase-cotação é útil quando um metaprograma escrito em Haskell manipula código escrito em uma linguagem diferente de Haskell.
  • Typeclasses genéricas , que especificam funções apenas em termos da estrutura algébrica dos tipos em que operam.
  • Avaliação paralela de expressões usando vários núcleos de CPU. Isso não requer threads de geração explicitamente. A distribuição do trabalho acontece de forma implícita, com base nas anotações fornecidas pelo programador.
  • Pragmas de compilador para direcionar otimizações, como expansão em linha e funções de especialização para tipos específicos.
  • Regras de reescrita personalizáveis. O programador pode fornecer regras que descrevem como substituir uma expressão por uma expressão equivalente, mas avaliada com mais eficiência. Eles são usados ​​nas bibliotecas de estrutura de dados principais para fornecer desempenho aprimorado em todo o código de nível de aplicativo.
  • Sintaxe de ponto de registro. Fornece açúcar sintático para acessar os campos de um registro (potencialmente aninhado) que é semelhante à sintaxe de muitas outras linguagens de programação.

Digite as extensões do sistema

Um sistema de tipo estático expressivo é uma das principais características definidoras de Haskell. Conseqüentemente, muito do trabalho de estender a linguagem foi direcionado para tipos e classes de tipos .

O Glasgow Haskell Compiler suporta um sistema de tipo estendido com base no teórico Sistema F C . As principais extensões do sistema de tipos incluem:

  • Polimorfismo de classificação arbitrária e impredicativo . Essencialmente, uma função polimórfica ou construtor de tipo de dados pode exigir que um de seus argumentos seja polimórfico.
  • Tipos de dados algébricos generalizados . Cada construtor de um tipo de dados polimórfico pode codificar informações no tipo resultante. Uma função que corresponde a um padrão neste tipo pode usar as informações de tipo por construtor para realizar operações mais específicas nos dados.
  • Tipos existenciais . Eles podem ser usados ​​para "empacotar" alguns dados junto com as operações nesses dados, de forma que as operações possam ser usadas sem expor o tipo específico dos dados subjacentes. Esse valor é muito semelhante a um objeto encontrado em linguagens de programação orientadas a objetos .
  • Tipos de dados que não contêm nenhum valor. Eles podem ser úteis para representar dados na metaprogramação em nível de tipo .
  • Famílias de tipo : funções definidas pelo usuário de tipos a tipos. Enquanto o polimorfismo paramétrico fornece a mesma estrutura para cada instanciação de tipo, as famílias de tipo fornecem polimorfismo ad hoc com implementações que podem diferir entre as instanciações. Os casos de uso incluem contêineres de otimização com reconhecimento de conteúdo e metaprogramação em nível de tipo.
  • Parâmetros de função implícita que têm escopo dinâmico . Eles são representados em tipos da mesma maneira que as restrições de classe de tipo.
  • Tipos lineares (GHC 9.0)

As extensões relacionadas às classes de tipo incluem:

  • Uma classe de tipo pode ser parametrizada em mais de um tipo. Assim, uma classe de tipo pode descrever não apenas um conjunto de tipos, mas uma relação n -ary em tipos.
  • Dependências funcionais , que restringem partes dessa relação para serem uma função matemática em tipos. Ou seja, a restrição especifica que algum parâmetro de classe de tipo é completamente determinado uma vez que algum outro conjunto de parâmetros seja corrigido. Isso orienta o processo de inferência de tipo em situações onde, de outra forma, haveria ambigüidade.
  • Regras significativamente relaxadas em relação à forma permitida de instâncias de classe de tipo. Quando eles estão totalmente habilitados, o sistema de classes de tipo torna -se uma linguagem Turing-completa para programação lógica em tempo de compilação.
  • As famílias de tipo, conforme descrito acima, também podem ser associadas a uma classe de tipo.
  • A geração automática de certas instâncias de classe de tipo é estendida de várias maneiras. Novas classes de tipo para programação genérica e padrões de recursão comuns são suportados. Além disso, quando um novo tipo é declarado como isomórfico a um tipo existente, qualquer instância de classe de tipo declarada para o tipo subjacente pode ser elevada para o novo tipo "gratuitamente".

Portabilidade

Versões do GHC estão disponíveis para várias plataformas , incluindo Windows e muitas variedades de Unix (como Linux , FreeBSD , OpenBSD e macOS ). GHC também foi transferido para várias arquiteturas de processador diferentes .

Veja também

Referências

links externos