Estou interessado em programação funcional e decidi entrar em confronto com Haskell. Minha cabeça dói ... mas acabo entendendo ... Tenho uma curiosidade, por que a sintaxe é tão enigmática (na falta de outra palavra)?
Existe uma razão pela qual não é mais expressivo , mais próximo da linguagem humana?
Entendo que o FP é bom em modelar conceitos matemáticos e emprestou alguns de seus meios concisos de expressão, mas ainda não é matemática ... é uma linguagem.
Respostas:
Linguagens funcionais como Haskell e seu antecedente Miranda surgiram do conceito matemático do cálculo lambda . Na página da Wikipedia:
Devido a essa história, as sintaxes dessas linguagens funcionais (e elementos funcionais de linguagens mais imperativas) são fortemente influenciadas pela notação matemática usada pelo cálculo lambda.
A precisão com a qual as notações matemáticas e as linguagens de computador podem descrever os requisitos e a precisão com a qual os computadores exigem que suas instruções sejam escritas estão bem correlacionadas. A imprecisão da linguagem natural, no entanto, cria uma enorme barreira ao seu uso na programação de computadores. Mesmo os ambientes de programação de linguagem natural (sem dúvida) mais bem-sucedidos , como o Wolfram Alpha, precisam de uma experiência significativa no domínio para serem usados com eficiência.
fonte
A sintaxe de Haskell está próxima da linguagem humana. Ele é projetado especificamente para se parecer com notação matemática, que é uma linguagem projetada por seres humanos (portanto, uma linguagem humana ) para expressar precisamente os conceitos nos quais Haskell se baseia.
Você pode mostrar um pedaço de código Haskell a qualquer matemático ou lógico, e ele será capaz de entendê-lo, mesmo que nunca tenha ouvido falar de Haskell e não saiba absolutamente nada sobre programação, ciência da computação ou mesmo computadores.
Por outro lado, você pode mostrar a qualquer matemático ou lógico um pedaço de código como este:
e ele ficará totalmente confuso, dizendo: "Isso não faz sentido, não existe
x
tal quex
seja igual ax
mais1
".Se uma notação específica é ou não "enigmática" ou não, é uma questão de opinião e familiaridade.
fonte
where
permitir a condensar a essência do uma função em uma linha.x = infinity
isso realmente resolve a equação.Eu acho que uma coisa em que você provavelmente está se deparando é algo que eu também encontrei ao aprender programação funcional, que é que, com a programação funcional, você pode (e quase precisa) pensar / trabalhar em um nível mais alto do que na programação imperativa.
O que você acha menos expressivo, acho que é realmente mais expressivo: você não precisa explicar todos os detalhes e pode fazer mais com menos código na programação funcional - há mais poder no que você escreve.
Por exemplo, eu poderia escrever imperativamente:
que é totalmente legível como o inglês.
Uma versão Haskell pode ser (e isso não é válido, mas é apenas para comparação sintática):
que requer menos código e menos detalhes - não preciso dividir as coisas em um loop e suas variáveis (
for each (...)
), amap
função cuida disso para mim.Trabalhar nesse nível pode levar algum tempo para se acostumar. Se isso ajuda, Haskell foi provavelmente o período mais difícil em que aprendi um novo idioma desde que comecei a programar e conheço mais de 10 idiomas (incluindo Lisp). Valeu a pena aprender totalmente.
fonte
Atualmente, estou começando a lidar com o Scala no momento, para que eu possa simpatizar. Pelo menos com Scala, posso voltar a um estilo imperativo quando as coisas ficam muito difíceis.
Eu acho que há várias forças em jogo aqui:
Os projetistas de linguagens funcionais necessariamente têm uma sólida formação em matemática, portanto tomam emprestada a notação matemática que é natural para eles.
Maior expressividade (ou seja, poder de declarações, em vez de proximidade com o inglês) de qualquer idioma tem (IMO) um preço correspondente na inclinação da curva de aprendizado. A dispersão é uma qualidade altamente valorizada em Scala, com muitas coisas sendo opcionais.
As linguagens funcionais fazem as coisas de maneira muito diferente, para que as operações básicas não sejam mapeadas para construções imperativas.
fonte
Se entendi seu último comentário corretamente, sua pergunta é por que Haskell costuma usar operadores simbólicos em locais onde ele também pode usar palavras-chave alfanuméricas (ou nomes de funções)?
Em relação às palavras-chave, uma resposta seria que elas impedem o uso de determinadas palavras como nomes de variáveis. Por exemplo, eu sempre fico chateado quando quero chamar minhas variáveis
from
eto
em um idioma em que uma delas é uma palavra-chave - como no Python.Outra razão para operadores simbólicos em geral é a concisão. Isso realmente não se aplica a seus exemplos específicos de compreensão de lista (
<-
não é menor quein
), mas em muitos casos, é verdade.Outra razão é a legibilidade. Isso pode parecer contra-intuitivo, porque os operadores simbólicos geralmente são mais difíceis de aprender, já que seus "nomes" realmente não dizem nada sobre o que eles fazem (enquanto o nome de uma função costuma dizer), mas depois que você sabe o que um determinado operador faz, expressões com operadores simbólicos infix costumam ser mais fáceis de analisar para um ser humano do que uma com muitas chamadas de função de prefixo alfanumérico, uma vez que os operadores se distinguem visualmente mais facilmente dos operandos dessa maneira. Por exemplo, a maioria das pessoas concorda que
2 * 3 + 4
é mais facilmente legível queadd (mult 2 3) 4
ouadd(mult(2, 3), 4)
.fonte
Linguagens de computador imperativas geralmente não estão mais próximas das linguagens naturais do que, digamos, Haskell.
No entanto, alguns são projetados para se parecer mais com o inglês: Cobol e Hypercard, por exemplo. As lições que eu tiraria desses exemplos são:
A linguagem de computador Perl foi projetada com alguns aspectos mais sutis da linguagem natural em mente . Eu julgaria que o Perl se sai melhor do que o Cobol ou o Hypercard na usabilidade geral, mas as pessoas têm opiniões diferentes sobre o Perl.
fonte
Acho que Haskell fica tão parecido com a linguagem humana quanto é possível sem introduzir uma sintaxe maluca. Isso realmente faz muito sentido, por exemplo, com a
where
cláusula de adiar uma definição e com a sintaxe de compreensão da lista, que é exatamente o que eu escreveria em um quadro negro. Também evita caracteres estranhos, como chaves, e tem um uso liberal de indentação. O exemplo típico é quicksort:Admitido, é um exemplo simples, mas não conheço nenhum outro idioma que o deixe tão legível quanto este.
Fazer coisas mais complicadas pode se tornar difícil de ler no Haskell, mas isso tem a ver com o sistema de tipos, o IO restrito e não com a sintaxe.
Na verdade, eu diria que Haskell sacrificou a simplicidade sintática para acomodar uma sintaxe mais semelhante à linguagem humana. Um esquema semelhante a uma linguagem tem uma sintaxe muito distante do que um humano escreveria, mas é realmente simples explicar suas regras.
fonte
++ [p] ++
?Eu acho que a diferença tem a ver com a maneira como a programação funcional / declarativa faz declarações sobre um problema como se fosse um problema de matemática, onde a programação imperativa descreve um processo . No mundo dos negócios, os programas de computador envolvem ou substituem processos físicos; portanto, você pode achar uma linguagem que reflete isso mais intuitiva.
Acontece que o estilo funcional se presta ao uso seguro de vários processadores (porque minimiza a mutabilidade e os efeitos colaterais) - algo que veremos mais no futuro. Além disso, as linguagens funcionais mais modernas têm coleções com iteradores para os quais você pode passar funções. Esses métodos podem dividir sua carga de trabalho em vários processadores de maneira muito eficiente, sem que você saiba.
fonte