19 pontos por GN⁺ 2024-09-13 | 3 comentários | Compartilhar no WhatsApp
  • "Imprática", "acadêmica", "de nicho"

    • Essas são as reações que as pessoas mostram quando descobrem que minha linguagem de programação favorita é Haskell
    • Eu a uso não só em projetos de hobby, mas também para construir servidores web reais
    • Lidero equipes que trabalham com Haskell na Converge
  • Equívocos sobre Haskell

    • Problemas que podem ser resolvidos com uma linguagem de programação de propósito geral também podem ser resolvidos em outras linguagens
    • Muitos recursos adotados em Python, Rust, Typescript etc. foram inspirados em Haskell ou implementados de forma mais robusta nela
    • Isso parece uma variação da ideologia de "escolha tecnologias entediantes"
    • Existe a ideia equivocada de que programação não é matemática e de que elementos matemáticos devem ser excluídos
  • Objetivo deste texto

    • Tentar explicar de forma lógica por que Haskell é a melhor escolha para a maioria dos programadores
    • É especialmente útil para quem quer escrever software robusto com produtividade
    • Também enfatiza o lado divertido de escrever software
  • Desaprender e reaprender

    • A maioria dos programadores está acostumada ao paradigma imperativo
    • Haskell é uma linguagem puramente funcional, com uma curva de aprendizado íngreme
    • A própria linguagem Haskell é fácil de aprender se você se limitar a um subconjunto simples
    • A programação funcional exige uma mudança completa na forma de compor programas
    • Esse processo ajuda no crescimento como programador
    • Citação de Alan Perlis:

      Uma linguagem que não afeta a maneira como você pensa sobre programação não vale a pena conhecer.

Breve explicação da sintaxe

  • :: indica uma assinatura de tipo (ex.: myThing :: String)

  • Chamadas de função não usam parênteses; os argumentos são listados após o nome da função, separados por espaços (ex.: doSomething withThis withThat)

  • Em assinaturas de tipo, letras minúsculas são variáveis de tipo e representam qualquer tipo (ex.: head :: [a] -> a)

  • Há dois tipos de setas, -> e =>:

    • -> descreve o tipo de uma função (ex.: add1 :: Int -> Int)
    • => descreve restrições sobre variáveis de tipo e sempre vem primeiro (ex.: add1 :: Num a => a -> a)
  • Comentários começam com --

  • return é uma função comum, não tem o significado que você espera

  • do é açúcar sintático para fazer o código parecer imperativo

  • Há várias formas de atribuir valores a variáveis locais:

    let x = <something> in  
    <expression>  
    

    ou x <- <something>

  • Redução de erros

    • Em muitas linguagens, escreve-se uma grande quantidade de casos de teste para tornar o código "correto"
    • Haskell reduz bastante esse peso com seu sistema de tipos e programação puramente funcional
    • O poderoso sistema de tipos de Haskell fornece garantias concretas sobre o programa e as aplica com rigor
    • Características do sistema de tipos:
      • Não há tipos anuláveis
      • É possível expressar computações que podem falhar
      • Pattern matching e checagem de exaustividade
      • Evita primitiveness obsession de graça
  • Vantagens de não ter valores nulos

    • Como não existe valor null, você sempre sabe se um valor tem o tipo esperado
    • Isso evita erros em tempo de execução e reduz a superfície de falhas
  • Expressão de computações que podem falhar

    • Os tipos Maybe e Either são usados para expressar explicitamente computações que podem falhar
    • Maybe representa uma computação que pode ou não ter resultado
      safeHead :: [a] -> Maybe a  
      
    • Either pode ter dois tipos de valor (Left a ou Right b)
      validateAddress :: String -> Either AddressParseError ValidAddress  
      
  • Pattern matching e checagem de exaustividade

    • Todo o domínio de entrada precisa ser tratado; caso contrário, o compilador gera erro
    • Isso evita erros em tempo de execução e aumenta a confiabilidade do programa
  • Evitando primitive obsession

    • Com newtype, é fácil criar tipos semanticamente mais significativos
    newtype VenueName = VenueName String  
    newtype EventName = EventName String  
    
  • Vantagens da programação puramente funcional

    • Os dados são imutáveis, então não é preciso se preocupar com mutação de estado
    • Efeitos colaterais são tratados de forma explícita, e funções dependem apenas da entrada, sem efeitos colaterais
    • Isso aumenta a previsibilidade e a estabilidade do programa
  • Tratamento explícito de efeitos colaterais

    • O mônada IO é usado para separar e controlar efeitos colaterais no código
    • Pela assinatura de tipo de uma função, é possível saber que ela causa efeitos colaterais
    sendGreetings :: User -> IO Response  
    
  • Mônadas e controle de efeitos

    • Typeclasses e mônadas são usadas para codificar com precisão os efeitos que uma função pode executar
    • Isso evita efeitos colaterais não intencionais e aumenta a estabilidade do código
  • Fatores que aumentam a produtividade

    • Graças ao sistema de tipos poderoso e à natureza puramente funcional, fica fácil reutilizar código e generalizar conceitos
    • Conceitos como Functor e Monoid permitem aplicar os mesmos padrões a diferentes estruturas de dados
    fmap (+2) [1, 2, 3] -- [3, 4, 5]  
    fmap (+2) (Just 2) -- Just 4  
    
  • Refatoração sem medo

    • Graças ao rigor do compilador, há menos risco de introduzir novos bugs ao alterar o código
    • O sistema de tipos permite expressar com precisão o domínio do programa, então é possível modificar o código com tranquilidade
  • Melhor compreensão do programa

    • Com programação declarativa, é possível expressar com precisão o domínio do problema
    • Fica mais fácil entender o significado do programa e aumentar sua confiabilidade
    • Ao remover complexidade desnecessária, torna-se possível raciocinar sobre o programa de forma mais sólida
  • Tipos de dados algébricos e typeclasses

    • É possível construir linguagens específicas de domínio dentro de Haskell
    • Isso ajuda a entender e manter o programa
  • Programa de exemplo

    • Um pequeno utilitário contábil é escrito para aplicar de forma prática os conceitos de Haskell

Epílogo

  • Usar Haskell é prazeroso e produtivo
  • A combinação de um sistema de tipos poderoso e expressivo com programação puramente funcional torna Haskell especial
  • Outras linguagens também estão adotando esses recursos, mas em Haskell essas características estão na base da linguagem
  • Aprender Haskell vai mudar sua forma de pensar sobre programação

Opinião do GN⁺

  • Valor de aprender Haskell

    • Ajuda a ampliar a forma de pensar como programador
    • Entender o paradigma de programação funcional permite escrever código melhor em outras linguagens também
  • Ascensão da programação funcional

    • Tem pontos fortes em processamento paralelo e concorrência, sendo adequada ao ambiente moderno de computação
    • O controle de efeitos colaterais permite escrever código previsível
  • Comparação com outras linguagens

    • Existem linguagens como Rust e Scala que também suportam programação funcional, mas a pureza e o sistema de tipos de Haskell são incomparáveis
    • Os conceitos de Haskell podem ajudar no aprendizado de novas linguagens
  • Aplicabilidade prática

    • A curva de aprendizado inicial é íngreme, mas a produtividade melhora na medida do tempo investido
    • É útil em sistemas complexos ou em domínios sensíveis a erros
  • Comunidade e ecossistema

    • A comunidade de Haskell é ativa, e várias bibliotecas e ferramentas continuam sendo desenvolvidas
    • Participar de projetos open source pode ajudar a melhorar suas habilidades

3 comentários

 
cosine20 2024-09-19

Comecei com F#, que acrescenta praticidade.

 
savvykang 2024-09-13

ADT e pattern matching são legais, mas por favor parem de falar de monads e functors

 
GN⁺ 2024-09-13
Comentários do Hacker News
  • Haskell força você a escrever funções totais em vez de funções parciais

    • Haskell não impede recursão infinita
    • No ecossistema de PF que caminha para tipos dependentes, é importante garantir que o verificador de tipos não execute infinitamente
    • Muitas extensões ad hoc do Haskell causam problemas
    • Se você gosta da filosofia do Haskell, não deve se limitar apenas ao Haskell
    • A padronização do Haskell fracassou
    • A proposta de valor única do GHC pode ser o sistema de runtime do GHC
  • Uso Haskell há 10 anos, e as ferramentas melhoraram muito

    • ghcup, sandboxing do cabal e HLS são estáveis
    • Não encontrei muitas deficiências no ecossistema de bibliotecas
    • O tempo de compilação do Haskell ainda é incômodo
    • O tempo de compilação das dependências é longo
  • O sistema de tipos do Haskell não prova que as funções são totais

    • Em programação comum, provar totalidade não é útil
    • A maioria das pessoas verifica se o programa realmente funciona por meio de testes
  • A linguagem Haskell é boa, mas o ecossistema ainda tem um longo caminho pela frente

    • O compilador é lento
    • A capacidade de relatar erros é fraca
    • O primeiro erro interrompe o restante da compilação
    • As ferramentas ainda ficam atrás de outras linguagens funcionais
    • O ecossistema de bibliotecas é insuficiente
    • As ideias do Haskell influenciaram muitas outras linguagens
  • Quero usar Haskell ou outra linguagem funcional profissionalmente

    • Foi fácil aprender linguagens como Go
    • Quero aprender a construir uma base de código em linguagens funcionais
  • Haskell teve um grande impacto na forma de pensar sobre programação e na arquitetura de código

    • O sistema de tipos do Haskell é muito poderoso e fácil de entender
    • Foi divertido fazer micro-otimizações em código Haskell
    • As ferramentas ainda deixam a desejar
  • Haskell experimenta a preguiça no nível da linguagem

    • A avaliação preguiçosa pode ser obtida no nível da biblioteca padrão
  • A pureza extrema e a imutabilidade do Haskell são um problema

    • Muitos programadores expressam com mais facilidade loops procedurais/mutáveis
    • Rust usa um sistema de tipos competente e muitos idiomatismos funcionais, mas permite usar loops e mutabilidade
  • Haskell é muito adequado para software de lógica de negócios (BLOBS)

    • A maior parte da lógica de negócios pode ser modelada com tipos simples e pattern matching
    • Mantendo as partes simples, fica fácil ensinar até mesmo a colaboradores não técnicos
    • Haskell é divertido