- Com base na experiência de um desenvolvedor que usou Haskell por 8 anos e OCaml por 8 meses em produção, compara a sensação prática de desenvolvimento nas duas linguagens funcionais
- Haskell oferece uma sintaxe mais concisa e recursos de tipagem poderosos, mas a quantidade de opções pode facilmente desviar a atenção para design e abstrações
- OCaml, embora tenha menos recursos, é avaliada como uma linguagem em que é mais fácil focar na implementação graças a módulos de primeira classe, mutabilidade prática e um estilo de código previsível
- O ecossistema de Haskell é maior, mas escolher bibliotecas pode parecer uma habilidade à parte; o de OCaml é menor, mas as ferramentas necessárias funcionam melhor do que se imagina
- Ambas as linguagens são menores que as linguagens mainstream e suas bibliotecas padrão são quase mínimas, mas, se não houver grande dependência de um SDK específico, são plenamente utilizáveis para desenvolver aplicações industriais
Ponto de partida da comparação
- A base é a experiência de ter usado Haskell por 8 anos e OCaml por 8 meses em produção
- Os eixos de comparação são sintaxe, recursos da linguagem, ecossistema, ferramentas, mensagens do compilador e biblioteca padrão
- Ambas as linguagens evoluíram o bastante para atender a necessidades industriais reais, mas a preferência atual está mais próxima de OCaml
Sintaxe: Haskell é mais concisa, e OCaml também tem as vantagens da família ML
- Haskell consegue expressar ideias com pouquíssimos caracteres, transmitindo uma forte sensação de elegância sintática
- OCaml também é uma excelente linguagem da família ML, mas Haskell oferece um estilo mais implícito (tacit)
- No exemplo de somar números dentro de uma string, Haskell expressa isso de forma curta com
sum . map read . words, enquanto OCaml explicita, com pipelines, as etapas de dividir a string, converter e fazer o fold - A definição de um tipo de árvore binária expressa naturalmente tipos de dados algébricos nas duas linguagens
- Nos exemplos de parsing, ambas usam pattern matching e valores opcionais, mas Haskell usa notação do e
guard, enquanto OCaml usaOption.bindematchexplícito
Recursos: Haskell é rica, OCaml distrai menos
- Haskell tem tantos recursos que C++ parece um ponto de comparação adequado
- Muitos recursos servem como ferramentas para resolver problemas de forma sofisticada, mas podem levar a pensar no próprio modo de projetar a solução antes da implementação real
- Em Haskell, é fácil se perder no design ao escolher entre opções como
TypeFamilies,DataKindseGADTs - Situações ruins em projetos OCaml existentes costumam se limitar a nomes de variáveis insuficientes, pouca documentação ou funções com mais de 200 linhas, algo visto como administrável
- Por outro lado, projetos Haskell existentes podem apresentar uma complexidade difícil de enfrentar mesmo com 8 anos de experiência
- Por causa dessa diferença, a sensação é de maior produtividade em OCaml
-
Recursos compartilhados pelas duas linguagens
- Ambas oferecem sintaxe centrada em expressões, imutabilidade por padrão, funções de ordem superior, funções anônimas, tipos de dados algébricos e pattern matching
- Polimorfismo paramétrico, inferência de tipos, açúcar sintático para mônadas, garbage collector, multithreading e GADTs também estão disponíveis em ambas
-
Recursos mais marcantes em Haskell
- Haskell oferece pureza por padrão, avaliação preguiçosa componível, type classes, tipos de kind superior e extensões opcionais da linguagem
- Por ter muitos recursos poderosos, a forma de abstração pode variar bastante de projeto para projeto
-
Recursos mais marcantes em OCaml
- OCaml oferece módulos de primeira classe (first-class modules), variantes polimórficas (polymorphic variants), objetos, classes e herança, além de mutabilidade fácil de usar
- A amplitude de recursos é menor que a de Haskell, mas isso se traduz na vantagem de uma base de código mais previsível
Ecossistema: Haskell é maior, OCaml tem as soluções necessárias
- Ambas são linguagens funcionais de nicho, então é difícil esperar suporte de primeira classe dos frameworks mais recentes
- Ainda assim, há soluções para a maior parte das tarefas comuns e, dependendo do caso, é preciso escrever mais bindings customizados
- Em OCaml, também é possível encontrar pacotes necessários para o trabalho prático, como:
- otoml: parser TOML
- Mint Tea: framework de TUI
- ocaml-opentelemetry: instrumentação OpenTelemetry
- awsm: cliente AWS para OCaml
- petrol: API SQL rápida para OCaml
- O ecossistema de Haskell tem mais pacotes e soluções prontas para uso
- Para bibliotecas cliente da Stripe API, Haskell tem 13, enquanto OCaml tem 1; como a última alteração da versão em OCaml foi há 8 anos, ela é considerada praticamente equivalente a 0
- Em Haskell, mesmo depois de encontrar uma solução, é preciso decidir qual biblioteca escolher entre opções demais
- A escolha de bibliotecas é tratada quase como uma habilidade separada, a ponto de haver um texto sobre como avaliar bibliotecas
- Muitas bibliotecas novas em Haskell surgem não tanto para resolver outro problema, mas porque alguém quer escrevê-las de outro jeito, com outra abstração ou um recurso novo
- Projetar um logger com comonads pode ser mais interessante do que criar um cliente para a GitHub API e fazer bastante parsing de JSON
Ferramentas: Haskell é poderosa, mas irregular; OCaml funciona bem
- As ferramentas de Haskell combinam grandes pontos fortes com problemas de usabilidade
- Hoogle é uma ferramenta poderosa que permite pesquisar em todo o ecossistema apenas pela assinatura de tipo
- Por outro lado, há problemas como mensagens de erro das ferramentas de build, situações em que não se encontra um plano de build em um projeto que está funcionando, recompilação pela IDE após mudanças em pacotes e ausência de documentação da biblioteca padrão para versões específicas
- A experiência de usar ferramentas em Haskell combina momentos de surpresa sobre como outras linguagens são usadas sem essas ferramentas e momentos de surpresa sobre como usuários de Haskell convivem sem usabilidade essencial
- Como o ecossistema de OCaml é menor, há surpresa cada vez que se descobre algo que funciona
- O plugin OCaml para VSCode baseado em LSP funcionou sem ajustes adicionais e não apresentou problemas
- Mesmo que a experiência inicial com as ferramentas de OCaml não seja a mais confortável possível, ela é intuitiva, robusta e funciona corretamente na maior parte dos casos
-
Comparação de ferramentas
- Compilador: OCaml usa ocaml, Haskell usa ghc
- REPL: OCaml usa utop, Haskell usa ghci
- Ferramentas de build: OCaml usa dune, Haskell usa cabal e stack
- Gerenciador de pacotes e repositório: OCaml usa opam, Haskell usa cabal e Hackage
- Linter: OCaml usa zanuda, Haskell usa hlint
- Formatadores: OCaml usa ocamlformat e topiary, Haskell usa fourmolu, stylish-haskell, hindent e ormolu
- Busca por tipos e busca de código: OCaml usa Sherlodoc e Sherlocode, Haskell usa Hoogle e Hackage Search
- Playgrounds online e LSP: OCaml usa TryOCaml e ocaml-lsp, Haskell usa Haskell Playground e HLS
Mensagens do compilador: Haskell é verbosa, OCaml é concisa
- Em linguagens funcionais, o compilador é uma ferramenta central para entender por que o código não satisfaz as premissas pretendidas
- Portanto, as mensagens de erro precisam mostrar as informações necessárias de uma forma acessível
- As mensagens do compilador de Haskell têm muito contexto e são verbosas, com tendência a incluir informações repetidas ou dispersas
- As mensagens do compilador de OCaml são bastante concisas e, às vezes, concisas demais
- O programa de erro de exemplo é um código que tenta somar um inteiro e uma lista, como
x = 1 + [3, 1, 2]em Haskell elet x = 1 + [3; 1; 2]em OCaml
Biblioteca padrão: ambas são mínimas, e a qualidade da documentação de Haskell se destaca
- A biblioteca padrão molda o primeiro programa em uma linguagem e a experiência de uso posterior
- Uma boa biblioteca padrão é a base do sucesso de uma linguagem de programação, enquanto uma biblioteca padrão insuficiente pode gerar debates contínuos sobre bibliotecas padrão alternativas
- A visão é que uma biblioteca padrão desejável deveria se aproximar do modelo batteries-included
- A composição desejada inclui tipos semelhantes a Option, strings UTF-8, Map e HashMap, parsers JSON e XML, primitivas assíncronas etc.
- Para não ter de aprender a implementar ferramentas de build e rastreamento de dependências, a biblioteca padrão precisa oferecer mais funcionalidades
- Build Systems a la Carte é um material que analisa a área de rastreadores de dependências e ferramentas de build
- Tanto em Haskell quanto em OCaml, a biblioteca padrão é relativamente mínima
- Haskell não inclui Map nem HashMap
- OCaml não tem non-empty lists nem Bitraversable
- A biblioteca padrão de Haskell é
base, e OCaml usa a OCaml standard library - A qualidade da documentação de Haskell às vezes é boa a ponto de surpreender até desenvolvedores experientes
- A documentação de Haskell também tem vantagens como a função de navegar até o código-fonte, e o autor diz ter ouvido que algo assim também está em preparação para OCaml
-
Exemplos de documentação
- Exemplos da documentação de List em Haskell
- Exemplos da documentação de List em OCaml
- Mesmo para funções cujo resultado é óbvio, uma documentação centrada em exemplos dá uma noção imediata de como usar a API
Conclusão: ambas podem ser usadas em produção, mas a preferência atual é OCaml
- As duas linguagens evoluíram bastante para atender a necessidades industriais reais
- Em comparação com linguagens mainstream, ainda são linguagens pequenas
- Se a existência de um SDK específico não for uma dependência crítica, é possível desenvolver a próxima aplicação com prazer escolhendo qualquer uma das duas
- Atualmente, OCaml é avaliada como uma linguagem em que é mais fácil se concentrar em realmente construir algo
Ainda não há comentários.