Que idioma aprender depois de Haskell? [fechadas]

85

Como minha primeira linguagem de programação, decidi aprender Haskell. Sou formado em filosofia analítica e Haskell me permitiu criar de forma rápida e correta programas de interesse, por exemplo, transdutores para análise de linguagem natural, provadores de teoremas e intérpretes. Embora eu esteja programando há apenas dois meses e meio, achei a semântica e a sintaxe de Haskell muito mais fáceis de aprender do que as linguagens imperativas mais tradicionais e me sinto confortável (agora) com a maioria de suas construções.

Programar em Haskell é como feitiçaria, porém, e gostaria de ampliar meu conhecimento de programação. Gostaria de escolher uma nova linguagem de programação para aprender, mas não tenho tempo suficiente para escolher uma linguagem arbitrária, largá-la e repetir. Portanto, pensei em colocar a questão aqui, juntamente com várias estipulações sobre o tipo de linguagem que procuro. Alguns são subjetivos, outros têm como objetivo facilitar a transição de Haskell.

  • Sistema de tipo forte. Uma das minhas partes favoritas da programação em Haskell é escrever declarações de tipo. Isso ajuda a estruturar meus pensamentos sobre funções individuais e sua relação com o programa como um todo. Também torna mais fácil o raciocínio informal sobre a correção do meu programa. Estou preocupado com a correção, não com a eficiência.
  • Ênfase na recursão em vez de iteração. Eu uso construções iterativas em Haskell, mas as implemento recursivamente. No entanto, é muito mais fácil entender a estrutura de uma função recursiva do que um procedimento iterativo complicado, especialmente ao usar combinadores e funções de ordem superior como mapas, dobras e vinculação.
  • É gratificante aprender. Haskell é uma linguagem gratificante de se trabalhar. É um pouco como ler Kant. Minha experiência de vários anos atrás com C, entretanto, não foi. Não estou procurando C. A linguagem deve impor um paradigma conceitualmente interessante, o que, em minha opinião inteiramente subjetiva, os C-likes não fazem.

Pesando as respostas : são apenas anotações, é claro. Gostaria apenas de responder a todos que deram respostas bem formadas. Você tem sido muito útil.

1) Várias respostas indicaram que uma linguagem forte e com tipagem estática enfatizando a recursão significa outra linguagem funcional. Embora eu queira continuar trabalhando fortemente com Haskell, camccann e larsmans apontaram corretamente que outra linguagem assim "facilitaria demais a transição". Esses comentários foram muito úteis, porque não estou procurando escrever Haskell em Caml! Dos assistentes de prova, Coq e Agda parecem interessantes. Em particular, Coq forneceria uma introdução sólida à lógica construtiva e à teoria formal dos tipos. Eu gastei um pouco de tempo com predicado de primeira ordem e lógica modal (Mendellsohn, Enderton, alguns de Hinman), então eu provavelmente me divertiria muito com Coq.

2) Outros favoreceram fortemente o Lisp (Common Lisp, Scheme e Clojure). Pelo que percebi, tanto Common Lisp quanto Scheme têm excelente material introdutório ( On Lisp e The Reasoned Schemer , SICP ). O material no SICP faz com que eu me incline para o Scheme. Em particular, o Scheme por meio do SICP cobriria uma estratégia de avaliação diferente, a implementação de preguiça e uma chance de enfocar tópicos como continuações, intérpretes, computação simbólica e assim por diante. Finalmente, como outros apontaram, o tratamento de código / dados de Lisp seria inteiramente novo. Portanto, estou inclinado fortemente para a opção (2), um Lisp.

3) Terceiro, Prolog. Prolog tem uma riqueza de material interessante, e seu domínio principal é exatamente aquele no qual estou interessado. Ele tem uma sintaxe simples e é fácil de ler. Não posso comentar mais no momento, mas depois de ler uma visão geral do Prolog e folhear algum material introdutório, ele classifica com (2). E parece que o retrocesso do Prolog está sempre sendo invadido por Haskell!

4) Das linguagens principais, Python parece a mais interessante. Tim Yates faz os idiomas parecerem muito atraentes. Aparentemente, Python é freqüentemente ensinado a alunos do primeiro ano em CS; portanto, é conceitualmente rico ou fácil de aprender. Eu teria que fazer mais pesquisas.

Obrigado a todos por suas recomendações! Parece que um Lisp (Scheme, Clojure), Prolog ou um assistente de prova como Coq ou Agda são os principais idiomas recomendados.

danportin
fonte
34
2,5 meses não é tempo suficiente para aprender qualquer idioma em profundidade, desculpe estourar sua bolha.
Woot4Moo
20
Certamente é verdade. Não quis dizer que "aprendi" Haskell, o que quer que isso signifique. Eu quis dizer que me sinto confortável usando a linguagem. Eu claramente não vou "parar de aprender".
danportin em
10
@Michael: Codificar para correção em vez de eficiência é algo que eu adoraria ver mais de ...
Deniz Dogan
24
@ Woot4Moo: 2,5 meses é bastante tempo para ficar "confortável" com um idioma, no entanto. Duplamente se ele estiver familiarizado com a lógica formal e trabalhar com conceitos abstratos de sua formação em filosofia. Não ter que desaprender hábitos de outras línguas também ajudaria neste caso.
CA McCann,
8
@gnovice: Isso já foi perguntado várias vezes, certamente. Mas esta é a primeira vez que encontro alguém que fez sua primeira experiência de programação séria com Haskell. É como se a flecha do tempo tivesse se invertido ou algo assim.
Muhammad Alkarouri,

Respostas:

85

Gostaria de ampliar meus conhecimentos de programação. (...) Pensei em colocar a questão aqui, junto com várias estipulações sobre o tipo de linguagem que procuro. Alguns são subjetivos, outros têm como objetivo facilitar a transição de Haskell.

Sistema de tipo forte. (...) Também facilita o raciocínio informal sobre a correção do meu programa. Estou preocupado com a correção, não com a eficiência.

Ênfase na recursão em vez de iteração. (...)

Você pode estar facilitando a transição um pouco demais aqui, infelizmente. O sistema de tipos muito rígido e o estilo puramente funcional são característicos de Haskell e praticamente qualquer coisa que se assemelhe a uma linguagem de programação convencional exigirá que se comprometa pelo menos um pouco com um deles. Portanto, com isso em mente, aqui estão algumas sugestões gerais destinadas a reter muito do que você parece gostar em Haskell, mas com algumas mudanças importantes.

  • Desconsidere a praticidade e opte por "mais Haskell do que Haskell" : o sistema de tipos de Haskell está cheio de buracos, devido à não terminação e outros compromissos complicados. Limpe a bagunça e adicione recursos mais poderosos e você terá linguagens como Coq e Agda , onde o tipo de uma função contém uma prova de sua exatidão (você pode até ler a seta de função ->como uma implicação lógica!). Essas linguagens têm sido usadas para provas matemáticas e para programas com requisitos de correção extremamente altos. Coq é provavelmente a linguagem mais proeminente do estilo, mas Agda tem uma sensação mais Haskell (além de ser escrita no próprio Haskell).

  • Desconsidere os tipos, adicione mais magia : Se Haskell é feitiçaria, Lisp é a magia crua e primordial da criação. As linguagens da família Lisp (também incluindo Scheme e Clojure ) têm flexibilidade quase inigualável combinada com minimalismo extremo. As linguagens não têm essencialmente sintaxe, escrevendo o código diretamente na forma de uma estrutura de dados em árvore; a metaprogramação em um Lisp é mais fácil do que a não metaprogramação em algumas linguagens.

  • Comprometer um pouco e aproximar-se do mainstream : Haskell cai na ampla família de línguas fortemente influenciado pelo ML, qualquer um que você provavelmente poderia mudar para sem demasiado muita dificuldade. Haskell é um dos mais rigorosos quando se trata de garantias de correção de tipos e uso de estilo funcional, onde outros são frequentemente estilos híbridos e / ou fazem compromissos pragmáticos por vários motivos. Se você deseja alguma exposição ao OOP e acesso a várias plataformas de tecnologia convencionais, Scala na JVM ou F #no .NET têm muito em comum com o Haskell, ao mesmo tempo que fornecem interoperabilidade fácil com as plataformas Java e .NET. F # é suportado diretamente pela Microsoft, mas tem algumas limitações irritantes em comparação com Haskell e problemas de portabilidade em plataformas não Windows. Scala tem contrapartes diretas para mais do sistema de tipo de Haskell e potencial de plataforma cruzada do Java, mas tem uma sintaxe mais pesada e não tem o suporte de primeira parte poderoso que o F # desfruta.

A maioria dessas recomendações também é mencionada em outras respostas, mas espero que minha justificativa para elas ofereça algum esclarecimento.

CA McCann
fonte
4
Eu família de Coq e Agda você também pode olhar para Qi II .
Hynek -Pichi- Vychodil
Quais seriam as limitações irritantes do F # na sua opinião? Como alguém que está aprendendo F # em seu tempo livre, estou curioso para saber.
Lucas
7
@Lucas: O grande problema do Haskell é a falta de polimorfismo de tipo superior e classes de tipo. Além disso, algumas extensões específicas do GHC são muito boas. Nada disso é uma falha fatal, de forma alguma, mas depois de me acostumar com Haskell, parece um pouco desajeitado não ter essas coisas. Imagine ir do C # moderno de volta ao C # 1.x ...
CA McCann
@HyneK: Esta linguagem Qi 2 à primeira vista parece muito interessante e mais flexível do que Coq ou Adga. Parece que o autor decidiu desistir. Existe algum movimento para continuar trabalhando nessa linguagem? Eu não gostaria de aprender algo que já está meio morto.
Alex,
@Alex: parece que continua como Shen: shenlanguage.org
amindfv
20

Vou ser aquele cara e sugerir que você está pedindo a coisa errada.

Primeiro você diz que quer ampliar seus horizontes. Em seguida, você descreve o tipo de linguagem que deseja, e seus horizontes parecem incrivelmente com os horizontes que você já tem. Você não vai ganhar muito aprendendo sempre a mesma coisa.

Eu sugiro que você aprenda um Lisp - ou seja, Common Lisp, Scheme / Racket ou Clojure. Eles são todos digitados dinamicamente por padrão, mas apresentam algum tipo de sugestão de tipo ou digitação estática opcional. Racket e Clojure são provavelmente suas melhores apostas.

Clojure é mais recente e tem mais haskelismos como imutabilidade por padrão e muita avaliação preguiçosa, mas é baseado na Java Virtual Machine, o que significa que tem alguns defeitos estranhos (por exemplo, a JVM não suporta eliminação de chamada final, então a recursão é gentil de um hack).

O Racket é muito mais antigo, mas ganhou muito poder ao longo do caminho, como suporte a tipos estáticos e foco na programação funcional. Acho que você provavelmente vai tirar o máximo proveito do Racket.

Os sistemas de macro no Lisps são muito interessantes e muito mais poderosos do que qualquer coisa que você verá em qualquer outro lugar. Só isso já vale a pena olhar.

Mandril
fonte
3
Heh, da perspectiva de Haskell, a sugestão de tipo ou a digitação estática opcional não parecem muito diferentes da digitação completamente dinâmica. É uma mentalidade muito diferente. Dito isso, as linguagens Lisp-y são todos os tipos de diversão e são algo que acho que todo programador deveria passar pelo menos algum tempo aprendendo.
CA McCann de
19

Do ponto de vista do que se adapta à sua especialização, a escolha óbvia parece ser uma linguagem lógica como Prolog ou seus derivados. A programação lógica pode ser feita de maneira muito organizada em uma linguagem funcional (consulte, por exemplo, The Reasoned Schemer ), mas você pode gostar de trabalhar com o paradigma lógico diretamente.

Um sistema de prova de teorema interativo, como twelf ou coq, também pode impressionar.

sclv
fonte
2
Como você declara interesse em uma linguagem fortemente tipada, eu recomendo lambdaProlog, uma linguagem de programação lógica de ordem superior tipada. Uma implementação compilada é o Teyjus - code.google.com/p/teyjus (divulgação: eu trabalhei no Teyjus).
Zach Snow,
18

Aconselho você a aprender Coq , que é um poderoso assistente de prova com sintaxe que será confortável para o programador Haskell. O legal do Coq é que ele pode ser extraído para outras linguagens funcionais, incluindo Haskell. Existe até um pacote ( Meldable-Heap ) no Hackage que foi escrito em Coq, tinha propriedades comprovadas sobre seu funcionamento e depois extraído para Haskell.

Outra linguagem popular que oferece mais poder do que Haskell é Agda - eu não conheço Agda além de saber que ela é digitada de forma dependente, no Hackage, e bem respeitada por pessoas que respeito, mas esses são motivos bons o suficiente para mim.

Eu não esperaria que nenhuma dessas coisas fosse fácil. Mas se você conhece Haskell e deseja avançar para uma linguagem que dê mais poder do que o sistema de tipos Haskell, então eles devem ser considerados.

Thomas M. DuBuisson
fonte
1
Agda soa como o "próximo passo" natural de Haskell.
Deniz Dogan,
5
Também é importante notar que se, como um estudante de filosofia, ele tem muita experiência com lógica formal, os assistentes de prova do estilo Curry-Howard podem muito bem ser menos desconcertantes para ele do que seriam para a maioria dos programadores veteranos!
CA McCann
11

Como você não mencionou nenhuma restrição além de seus interesses subjetivos e enfatizou 'gratificante aprender' (bem, ok, vou ignorar a restrição de digitação estática), sugiro aprender algumas línguas de paradigmas diferentes, e de preferência aqueles que são 'exemplares' para cada um deles.

  • A Lisp dialeto para a coisa de code-as-data / homoiconicity e porque eles são bons, se não os melhores, exemplos de linguagens de programação funcional dinâmicas (mais ou menos estritas)
  • Prolog como linguagem de programação lógica predominante
  • Conversa fiada como a verdadeira linguagem OOP (também interessante por causa de sua abordagem geralmente extremamente centrada na imagem)
  • talvez Erlang ou Clojure se você estiver interessado em linguagens forjadas para programação concorrente / paralela / distribuída
  • Adiante para programação orientada a pilha
  • ( Haskell para programação preguiçosa com tipagem estática funcional estrita)

Especialmente Lisps (CL não tanto quanto Scheme) e Prolog (e Haskell) abraçam a recursão.

Embora eu não seja um guru em nenhuma dessas línguas, passei algum tempo com cada um deles, exceto Erlang e Forth, e todos eles me proporcionaram experiências de aprendizagem interessantes e reveladoras, pois cada um aborda a resolução de problemas de um ângulo diferente .

Portanto, embora possa parecer que ignorei a parte sobre você não ter tempo para experimentar alguns idiomas, prefiro pensar que o tempo gasto com qualquer um deles não será desperdiçado, e você deveria dar uma olhada em todos eles.

danlei
fonte
Eu não suportaria as restrições de Erlang envolvendo tutores;)
gorsky
10

Que tal uma linguagem de programação orientada a pilha ? Cat atinge seus pontos altos. Isto é:

  • Digitado estaticamente com inferência de tipo.
  • Faz você repensar os conceitos de linguagens imperativas comuns, como looping. A execução condicional e o loop são tratados com combinadores .
  • Recompensa - força você a entender outro modelo de computação. Oferece outra maneira de pensar e decompor os problemas.

O Dr. Dobbs publicou um pequeno artigo sobre Cat em 2008, embora a linguagem tenha mudado ligeiramente.

Corbin March
fonte
10

Se você deseja um Prolog de tipo forte (er), Mercury é uma escolha interessante. Já me interessei por isso no passado e gostei da perspectiva diferente que me deu. Ele também tem moded-ness (quais parâmetros precisam ser livres / fixos) e determinismo (quantos resultados existem?) No sistema de tipos.

Clean é muito semelhante a Haskell, mas tem tipagem única, que é usada como uma alternativa para Mônadas (mais especificamente, a mônada IO). A tipagem de exclusividade também faz coisas interessantes para trabalhar com arrays.

yatima2975
fonte
8

Apesar de não atender a um de seus grandes critérios (tipagem estática *), vou defender o Python. Aqui estão alguns motivos pelos quais eu acho que você deve dar uma olhada:

  • Para uma linguagem imperativa, é surpreendentemente funcional. Essa foi uma das coisas que me impressionaram quando aprendi. Veja as compreensões de lista , por exemplo. Possui lambdas, funções de primeira classe e muitas composições inspiradas em funções em iteradores (mapas, dobras, zips ...). Dá a você a opção de escolher o paradigma que melhor se adapta ao problema.
  • IMHO, é, como Haskell, bonito de codificar. A sintaxe é simples e elegante.
  • Tem uma cultura que se concentra em fazer as coisas de uma maneira direta, em vez de se concentrar minuciosamente na eficiência.

Eu entendo se você estiver procurando por outra coisa. A programação lógica, por exemplo, pode ser a sua escolha, como outros sugeriram.


* Presumo que você queira dizer digitação estática aqui, já que deseja declarar os tipos. Tecnicamente, Python é uma linguagem fortemente tipada, já que você não pode interpretar arbitrariamente, digamos, uma string como um número. Curiosamente, existem derivados do Python que permitem a digitação estática, como Boo .

Tim Yates
fonte
No entanto, o sistema de tipo forte não significa necessariamente apenas digitação "estática".
Deniz Dogan,
+1 também veja meu comentário sobre a resposta de larsmans. Mas tome cuidado para anunciar Python como bastante funcional. Por exemplo, gerador de expressões são geralmente preferidos sobre map, filteretc. Mas ainda assim, geradores e gerador de expressões será familiar a alguém que sabe avaliação preguiçosa e as funções disse.
16
Mesmo? Acho que Python parece particularmente funcional para pessoas que não fizeram muita programação funcional. Eu usei Python e Haskell bastante e, embora Python seja uma boa linguagem e certamente tenha emprestado algumas coisas de linguagens funcionais, ainda é 99% imperativo.
CA McCann,
@camccann Você está certo - minha perspectiva é diferente, e é por isso que estou oferecendo isso como uma alternativa interessante. Como alguém que aprendeu programação imperativa primeiro, eu aprecio que Python me permite usar técnicas funcionais onde elas são apropriadas e evitá-las onde algo mais faz sentido. Não estou afirmando que "é" funcional - apenas que é um bom compromisso.
Tim Yates,
Os hábitos aprendidos com Haskell podem torná-lo um programador Python muito melhor do que outros que o aprenderam como primeira linguagem.
u0b34a0f6ae
8

Eu recomendaria você Erlang. Não é uma linguagem de digitação forte e você deve experimentá-la. É uma abordagem muito diferente para a programação e você pode descobrir que há problemas em que a digitação forte não é a melhor ferramenta (TM). De qualquer forma, o Erlang fornece ferramentas para verificação estática de tipo (digitador, dialisador) e você pode usar uma digitação forte nas partes em que obtém benefícios. Pode ser uma experiência interessante para você, mas esteja preparado, será uma sensação bem diferente. Se você está procurando por "paradigma conceitualmente interessante", você pode encontrá-los em Erlang, troca de mensagens, separação de memória ao invés de compartilhamento, distribuição, OTP, tratamento de erros e propagação de erros em vez de "prevenção" de erros e assim. Erlang pode estar longe de sua experiência atual, mas ainda está fazendo cócegas no cérebro se você tiver experiência com C e Haskell.

Hynek -Pichi- Vychodil
fonte
8

Dada sua descrição, eu sugeriria Ocaml ou F # .

A família ML é geralmente muito boa em termos de um sistema de tipo forte. A ênfase na recursão, juntamente com o casamento de padrões, também é clara.

Onde estou um pouco hesitante é no gratificante de aprender . Aprendê-los foi gratificante para mim, sem dúvida. Mas, dadas suas restrições e sua descrição do que você quer, parece que você não está realmente procurando por algo muito mais diferente do que Haskell.

Se você não colocasse suas restrições, eu teria sugerido Python ou Erlang , ambos os quais o tirariam de sua zona de conforto.

Muhammad Alkarouri
fonte
6

Na minha experiência, forte digitação + ênfase na recursão significa outra linguagem de programação funcional. Então, novamente, eu me pergunto se isso é muito gratificante, visto que nenhum deles será tão "puro" quanto Haskell.

Como outros pôsteres sugeriram, Prolog e Lisp / Scheme são legais, embora ambos sejam digitados dinamicamente. Muitos livros excelentes, com um forte "gosto" teórico, foram publicados sobre Scheme em particular. Dê uma olhada no SICP , que também transmite muita sabedoria geral da ciência da computação (intérpretes metacirculares e similares).

Fred Foo
fonte
4
1 para o primeiro parágrafo, exatamente o que pensei quando li a pergunta. Para aprender coisas novas, eu sugeriria uma linguagem imperativa moderna, como Python - especialmente porque não é o que o OP costumava fazer (tipagem dinâmica, iteradores em todos os lugares, etc). Ele também tem conceitos avançados muito interessantes como metaclasses ou geradores (que são muito semelhantes a listas preguiçosas) / expressões geradoras (que servem como uma generalização de compreensões de lista + geradores). Além disso, dite e defina a regra de compreensão.
3
@delnan: Haskell também tem compreensões de lista e geradores / iteradores podem ser facilmente expressos em Haskell usando o tipo de lista padrão de Haskell. Portanto, as maiores diferenças entre as duas linguagens seriam, em minha opinião, a programação orientada a objetos e (na maioria das vezes) estruturas de dados impuras, como dicionários.
Deniz Dogan,
1
@Deniz Dogan: não se esqueça da falta de declarações e escopo léxico adequado em Python.
Fred Foo,
5

Você pode começar a pesquisar no Lisp .

Prolog é uma linguagem legal também.


fonte
5

Se você decidir se desviar de sua preferência por um sistema de tipos, pode se interessar pela linguagem de programação J. É notável por enfatizar a composição de funções. Se você gosta do estilo sem pontos em Haskell, a forma tácita de J será recompensadora. Achei extraordinariamente instigante, especialmente no que diz respeito à semântica.

É verdade que não se encaixa em seus preconceitos sobre o que você gostaria, mas dê uma olhada. Vale a pena descobrir apenas saber que está lá fora. A única fonte de implementações completas é J Software, jsoftware.com.

caleídico
fonte
0

Vá com um dos fluxos principais. Dados os recursos disponíveis, a capacidade de comercialização futura de sua habilidade, ecossistema de desenvolvedor rico, acho que você deve começar com Java ou C # .

Angkor Wat
fonte
14
Comparado com Haskell, ambos são linguagens bastante coxas IMO.
missingfaktor,
9
Pedir a um Haskeller que se mude para Java é como pedir a Bill Gates que se mude para uma favela. : - /
missingfaktor,
1
+1 Por sugerir algo que definitivamente fará com que você seja reprovado. Java e C # têm bons ecossistemas e são ambos muito recomendados para trabalhos sérios. Como uma vantagem definitiva, você pode alavancar seu conhecimento de Haskell (, Java e C #) ao usar Clojure no JVM ou F # no CLR.
ponzao
6
@ponzao: Urgh, não, sugerir que alguém vá de Haskell para Java ou C # é simplesmente horrível e cruel. Scala, F # e Clojure são linguagens muito mais agradáveis ​​com todos os mesmos benefícios que vêm da execução no JVM / CLR.
CA McCann
5
Para uma filosofia analítica, Java ou C # principais são uma perda de tempo.
MaD70,
0

Ótima pergunta - tenho me perguntado recentemente depois de passar vários meses curtindo Haskell, embora minha formação seja muito diferente (química orgânica).

Como você, C e seus semelhantes estão fora de questão.

Tenho oscilado entre Python e Ruby como as duas linguagens de script burras de carga práticas hoje (mulas?) E ambas têm alguns componentes funcionais para me manter feliz. Sem iniciar qualquer debate Rubista / Pythonista aqui, mas minha resposta pragmática pessoal a esta pergunta é:

Aprenda aquele (Python ou Ruby) que você primeiro arranja uma desculpa para aplicar.

jdo
fonte