Eu li alguns textos sobre programação declarativa / funcional (linguagens), experimentei Haskell e também escrevi um. Pelo que vi, a programação funcional tem várias vantagens sobre o estilo imperativo clássico:
- Programas sem estado; Sem efeitos colaterais
- Concorrência; Joga extremamente bem com a crescente tecnologia multi-core
- Os programas geralmente são mais curtos e, em alguns casos, mais fáceis de ler
A produtividade aumenta (exemplo: Erlang)
A programação imperativa é um paradigma muito antigo (tanto quanto eu sei) e possivelmente não é adequado para o século XXI
Por que as empresas que usam ou programas escritos em linguagens funcionais ainda são "raras"?
Por que, quando analisamos as vantagens da programação funcional, ainda estamos usando linguagens de programação imperativas?
Talvez fosse muito cedo para isso em 1990, mas hoje?
functional-programming
pankrax
fonte
fonte
Respostas:
Porque todas essas vantagens também são desvantagens.
Programas do mundo real são sobre efeitos colaterais e mutações. Quando o usuário pressiona um botão, é porque ele quer que algo aconteça. Quando digitam algo, querem que esse estado substitua o estado que costumava estar lá. Quando Jane Smith, na contabilidade, se casa e muda seu nome para Jane Jones, é melhor o banco de dados que apóia o processo de negócios que imprime sua folha de pagamento trata de lidar com esse tipo de mutação. Quando você dispara a metralhadora contra o alienígena, a maioria das pessoas não o modela mentalmente como a construção de um novo alienígena com menos pontos de vida; eles modelam isso como uma mutação das propriedades de um alienígena existente.
Quando os conceitos da linguagem de programação funcionam fundamentalmente contra o domínio que está sendo modelado, é difícil justificar o uso dessa linguagem.
O problema é apenas empurrado. Com estruturas de dados imutáveis, você tem segurança de encadeamento barata, ao custo de possivelmente trabalhar com dados obsoletos. Com estruturas de dados mutáveis, você tem o benefício de sempre trabalhar em dados novos, ao custo de ter que escrever uma lógica complicada para manter os dados consistentes. Não é como se um deles fosse obviamente melhor que o outro.
Exceto nos casos em que são mais longos e difíceis de ler. Aprender a ler programas escritos em um estilo funcional é uma habilidade difícil; as pessoas parecem muito melhores em conceber os programas como uma série de etapas a serem seguidas, como uma receita, e não como uma série de cálculos a serem realizados.
A produtividade precisa aumentar muito para justificar as enormes despesas de contratação de programadores que sabem como programar em um estilo funcional.
E lembre-se, você não quer jogar fora um sistema em funcionamento; a maioria dos programadores não está construindo novos sistemas a partir do zero, mas mantendo sistemas existentes, a maioria dos quais foi construída em linguagens não funcionais. Imagine tentar justificar isso para os acionistas. Por que você descartou seu sistema de folha de pagamento em funcionamento existente para criar um novo com o custo de milhões de dólares? "Porque a programação funcional é impressionante" é improvável que encante os acionistas.
A programação funcional também é muito antiga. Não vejo como a idade do conceito é relevante.
Não me interpretem mal. Adoro programação funcional, entrei para essa equipe porque queria ajudar a trazer conceitos da programação funcional para o C # e acho que a programação em um estilo imutável é o caminho do futuro. Mas existem enormes custos para a programação em um estilo funcional que não pode simplesmente ser desperdiçado. A mudança para um estilo mais funcional acontecerá lenta e gradualmente ao longo de décadas. E é isso que será: uma mudança para um estilo mais funcional, não um abraço generalizado da pureza e beleza de Haskell e o abandono do C ++.
Eu construo compiladores para ganhar a vida e definitivamente estamos adotando um estilo funcional para a próxima geração de ferramentas de compilador. Isso porque a programação funcional é fundamentalmente uma boa combinação para os tipos de problemas que enfrentamos. Nossos problemas consistem em coletar informações brutas - strings e metadados - e transformá-las em strings e metadados diferentes. Nas situações em que ocorrem mutações, como se alguém estivesse digitando no IDE, o espaço do problema se presta inerentemente a técnicas funcionais, como a reconstrução incremental de apenas as partes da árvore que foram alteradas. Muitos domínios não possuem essas boas propriedades que os tornam obviamente acessíveis a um estilo funcional .
fonte
Masterminds of Programming: Conversas com os criadores das principais linguagens de programação
fonte
A resposta das ações é que nenhuma delas substituirá ou substituirá a outra - elas são ferramentas diferentes, com diferentes conjuntos de prós e contras, e cuja abordagem tem vantagens diferirá dependendo do projeto e de outros problemas "leves", como o conjunto de talentos disponíveis.
Acho que você está certo de que o crescimento da simultaneidade devido ao multi-core aumentará a porcentagem (do conjunto global de projetos de desenvolvimento) quando a programação funcional é escolhida em detrimento de outros estilos.
Acho que hoje é raro, porque a maioria dos talentos profissionais atuais se sente mais à vontade com tecnologias imperativas e orientadas a objetos. Por exemplo, mais de uma vez escolhi o Java como a linguagem para um projeto comercial porque era bom o suficiente, não controverso, e sei que nunca ficarei sem pessoas que possam programar (bem o suficiente) nele.
fonte
Apesar das vantagens da programação funcional, a programação imperativa e orientada a objetos nunca desaparece completamente.
A programação imperativa e orientada a objetos é uma descrição passo a passo do problema e de sua solução. Como tal, pode ser mais fácil de entender. A programação funcional pode ser um pouco obscura.
Por fim, um programa útil sempre terá efeitos colaterais (como fornecer saída real ao usuário para consumo); portanto, a mais pura das linguagens funcionais ainda precisará de uma maneira de entrar no mundo imperativo de tempos em tempos.
O estado da arte atual é que linguagens imperativas (como C #) tomam emprestado recursos do mundo funcional (como instruções lambda) e vice-versa.
fonte
Não é?
O Smalltalk era um ótimo sistema orientado a objetos na época. Por que a programação orientada a objetos não assumiu? Bem, tem. Simplesmente não se parece com Smalltalk. As linguagens mainstream continuam ficando mais parecidas com Smalltalk com C ++, Java, C # etc. A moda e o estilo mudam mais devagar do que qualquer coisa; portanto, quando o OO se tornou mainstream, conseguimos obtê-lo colando partes do OO em idiomas antigos, para que parecesse o suficiente para C engolir .
Funcional é da mesma maneira. Haskell era uma ótima linguagem funcional. Mas temos ainda mais massa de programadores tradicionais usando sintaxe do tipo C hoje do que há 20 anos. Portanto, ele deve se parecer com C. Concluído: observe qualquer expressão LINQ e me diga que não é funcional.
fonte
dynamic
. Esse é o mais Smalltalk-y desses recursos, então não é surpresa para mim que ele esteja presente apenas na versão mais recente do mais moderno desses três idiomas. :-)Acredito que linguagens imperativas são mais predominantes simplesmente porque é a isso que mais pessoas estão acostumadas. Nem a programação funcional nem o modelo de programação imperativa são mais obscuros ou acadêmicos do que o outro. De fato, são complementos.
Um pôster dizia que o código imperativo é mais fácil de entender do que o código de programação funcional. Isso só é verdade se o leitor já tiver visto código imperativo, especialmente se os exemplos anteriores fizerem parte da mesma "família" (por exemplo, C / C ++, Perl, PHP e Java). Eu não diria que isso é verdade para qualquer linguagem imperativa; faça uma comparação entre Java e Forth, para dar um exemplo extremo.
Para um leigo, todas as linguagens de programação são bobagens indecifráveis, exceto talvez as linguagens detalhadas, como Hypertalk e SQL. (De notar, o SQL é uma linguagem declarativa e / ou funcional e goza de enorme popularidade.)
Se tivéssemos sido treinados inicialmente em uma linguagem Lisp-y ou Haskell-y desde o início, todos pensaríamos que as linguagens de programação funcional são perfeitamente normais.
fonte
Você já obteve respostas suficientes para mencionar apenas algumas coisas que ainda não vi mencionadas.
Primeiro e (em minha opinião), as linguagens processuais se beneficiaram muito de seu grau de comunalidade. Por exemplo, quase todo mundo que conhece quase todas as linguagens processuais (OO) convencionais em quase qualquer grau pode ler a maioria das outras razoavelmente bem. Eu evito trabalhar ativamente em Java, C #, Cobol, Fortran ou Basic (por apenas alguns exemplos), mas consigo ler qualquer um deles razoavelmente bem - quase tão bem, na verdade, quanto as pessoas que os usam todos os dias.
No lado funcional, isso é muito menos verdadeiro. Apenas por exemplo, também posso escrever Scheme de maneira bastante razoável, mas isso é de pouca utilidade na leitura de Ocaml ou Haskell (por apenas alguns exemplos). Mesmo dentro de uma única família (por exemplo, Scheme vs., Common Lisp), a familiaridade com uma parece não se traduzir tão bem na outra.
A afirmação de que o código funcional é mais legível tende a ser verdadeira apenas sob uma faixa estreita de condições. Para pessoas que estão extremamente familiarizadas com o idioma, a legibilidade é realmente excelente - mas para todos os outros, geralmente é quase inexistente. Pior, enquanto as diferenças nas linguagens procedurais são amplamente de sintaxe e, portanto, relativamente fáceis de aprender, as diferenças nas linguagens funcionais são muitas vezes muito mais fundamentais, portanto, requerem um estudo considerável para realmente entender (por exemplo, saber que o Lisp é de pouca ajuda na compreensão das mônadas).
O outro ponto importante é que a idéia de que os programas funcionais são mais curtos que os processuais geralmente se baseia mais na sintaxe do que na semântica. Os programas escritos em Haskell (por exemplo) são frequentemente bastante curtos, mas seu funcionamento é uma parte bastante pequena disso. Muita coisa, se é que Haskell tem uma sintaxe relativamente concisa.
Poucas linguagens puramente funcionais podem competir bem com o APL pelo código fonte conciso (embora, para ser justo, o APL também suporte a criação de funções de nível superior, portanto, essa não é uma diferença muito grande, como em outros casos). Por outro lado, Ada e C ++ (apenas para alguns exemplos) podem ser bastante competitivos em termos de número de operações necessárias para realizar uma determinada tarefa, mas a sintaxe é (pelo menos geralmente) substancialmente mais detalhada.
fonte
Nenhuma necessidade percebida
Lembro-me da resposta do meu antigo chefe Rick Cline quando lhe mostrei uma cópia da palestra do John Backus 'Turing Award, intitulada Pode-se libertar a programação do estilo von Neumann?
Sua resposta: "Talvez alguns de nós não desejem se libertar do estilo von Neumann!"
fonte
Funcional é melhor para algumas coisas e pior para outras, para que nunca "assuma o controle". Já é onipresente no mundo real.
Programas sem estado são mais fáceis de testar. Agora isso é amplamente apreciado e frequentemente explorado na indústria.
Você está confluindo concorrente e paralelismo.
A simultaneidade pode ser feita efetivamente usando processos sequenciais de comunicação (CSP). O código dentro de um CSP pode alterar seu estado local, mas as mensagens enviadas entre eles sempre devem ser imutáveis.
A programação puramente funcional é extremamente ruim com o multicore porque é muito hostil ao cache. Os núcleos acabam competindo pela memória compartilhada e os programas paralelos não são redimensionados.
O Scala é frequentemente considerado como uma linguagem funcional, mas não é mais funcional que o C #, que é uma das línguas mais populares do mundo atualmente.
A programação puramente funcional tem muitas desvantagens sérias, por isso usamos linguagens funcionais impuras como Lisp, Scheme, SML, OCaml, Scala e C #.
fonte
Quando penso no que a programação funcional pode trazer para meus projetos no trabalho, sempre sou conduzida pelo mesmo caminho:
Para obter todas as vantagens da programação funcional, você precisa de preguiça. Sim, existem linguagens funcionais estritas, mas os benefícios reais da programação funcional não brilha tão bem no código estrito. Por exemplo, em Haskell, é fácil criar uma sequência de operações preguiçosas em uma lista e concatená-las e aplicá-las a uma lista. Por exemplo.
op1 $ op2 $ op3 $ op4 $ someList
. Eu sei que não vai construir a lista inteira e, internamente, só vou obter um loop agradável que percorre os elementos um de cada vez. Isso permite que você escreva um código realmente modular. A interface entre dois módulos pode envolver a entrega de estruturas de dados potencialmente vastas e, no entanto, você não precisa ter a estrutura residente.Mas quando você tem preguiça, fica difícil argumentar sobre o uso da memória. Alterar os sinalizadores do compilador Haskell frequentemente altera a quantidade de memória usada por um algoritmo de O (N) para O (1), exceto que às vezes não. Isso não é realmente aceitável quando você tem aplicativos que precisam aproveitar ao máximo toda a memória disponível e não é ótimo, mesmo para aplicativos que não precisam de toda a memória.
fonte
Duas coisas:
fonte