Ultimamente, tenho notado que linguagens de programação funcional estão ganhando popularidade . Vi recentemente como o Índice Tiobe mostra um aumento em sua popularidade em comparação com o ano passado, embora a maioria nem chegue aos 50 idiomas mais populares de acordo com esse índice.
E esse tem sido o caso há algum tempo. A programação funcional simplesmente não se tornou tão popular quanto outros modelos (isto é, programação orientada a objetos).
Entretanto, vi um interesse renascido no poder da programação funcional e agora que os multicores são cada vez mais populares, os desenvolvedores começaram a mostrar interesse em outros modelos de concorrência já explorados no passado por linguagens como Haskell e Erlang.
Vejo com grande interesse o fato de que, apesar da falta de aceitação significativa da comunidade, mais e mais idiomas desse tipo continuam surgindo. Clojure (2007), Scala (2003), F # (2002) são apenas três exemplos da década passada.
Eu próprio investi algum tempo aprendendo Haskell e Scala. E encontro um grande potencial no paradigma que, para mim, era novo, apesar de estar lá por tanto tempo.
E, claro, minha maior pergunta é se alguma dessas coisas se tornará popular o suficiente para considerar colocar algum esforço nelas, mas essa é uma pergunta que nem Mandrake poderia responder, apesar de todo o barulho que as pessoas estão fazendo sobre elas.
O que eu quero perguntar é:
- Em quais cenários devo considerar uma linguagem de programação funcional mais adequada para executar uma determinada tarefa? Além do tão recentemente popular problema multicore da programação paralela.
- Se eu decidisse mudar para uma linguagem de programação funcional que você consideraria as maiores armadilhas que eu enfrentaria? (Além da mudança de paradigma e da dificuldade de avaliar o desempenho devido à avaliação preguiçosa).
- Com tantas linguagens de programação funcionais por aí, como você escolheria a que melhor se adequa às suas necessidades?
Quaisquer recomendações para futuras pesquisas serão mais que bem-vindas.
Pesquisei opiniões na Web e parece que toda essa popularidade renovada vem da idéia de que agora estamos prestes a atingir a lei de Moore e as linguagens de programação funcionais virão e nos salvarão heroicamente. Mas, se esse for o caso, eu diria que há mais probabilidades de as linguagens populares existentes se adaptarem ao paradigma.
Alguns de vocês, com mais experiência trabalhando todos os dias com esses idiomas, talvez possam oferecer mais informações sobre o assunto. Todas as suas opiniões serão melhor apreciadas e cuidadosamente consideradas.
Desde já, obrigado!
Respostas:
Qualquer coisa que envolva a criação de sequência de elementos de dados derivados usando várias etapas de transformação.
Essencialmente, o "problema da planilha". Você tem alguns dados iniciais e um conjunto de cálculos linha a linha para aplicar a esses dados.
Nossos aplicativos de produção fazem vários resumos estatísticos de dados; tudo isso é melhor abordado funcionalmente.
Uma coisa comum que fazemos é uma combinação de correspondência entre três conjuntos de dados monstruosos. Semelhante a uma junção SQL, mas não tão generalizada. Isto é seguido por vários cálculos de dados derivados. Tudo isso são apenas transformações funcionais.
O aplicativo é escrito em Python, mas é escrito em um estilo funcional usando funções de gerador e tuplas nomeadas imutáveis. É uma composição de funções de nível inferior.
Aqui está um exemplo concreto de uma composição funcional.
Essa é uma maneira pela qual a programação funcional influencia linguagens como Python.
Às vezes, esse tipo de coisa é escrito como:
Objetos imutáveis é o obstáculo mais difícil.
Geralmente, você acaba calculando valores que criam novos objetos em vez de atualizar objetos existentes. A idéia de que é um atributo mutável de um objeto é um hábito mental difícil de ser quebrado.
Uma propriedade derivada ou função de método é uma abordagem melhor. Objetos com estado são um hábito difícil de quebrar.
Não importa a princípio. Escolha qualquer idioma para aprender. Depois de saber algo, você estará em uma posição que considere escolher outro para melhor atender às suas necessidades.
Eu li Haskell apenas para entender o que falta ao Python.
fonte
"Funcional" é um monte de recursos diferentes, cada um dos quais é útil independentemente, e acho mais útil olhar para cada um individualmente.
Imutabilidade
Agora que estou familiarizado, sempre que posso retornar um resultado imutável, sempre tento fazer isso, mesmo em um programa orientado a objetos. É mais fácil argumentar sobre o programa se você tiver dados do tipo valor. Geralmente, você precisa de mutabilidade para coisas como GUIs e gargalos de desempenho. Minhas entidades (usando NHibernate) também são mutáveis (o que faz sentido porque estão modelando dados armazenados em um banco de dados).
Funções como tipos de primeira classe
Como você quiser chamar, delegando delegados, ações ou funções, é uma maneira realmente útil de resolver toda uma classe de problemas do mundo real, como o "buraco no padrão intermediário". Também descobri que passar um delegado, ação ou função para um objeto é mais limpo do que fazer com que essa classe declare um evento e ligue esse evento (supondo que normalmente haja apenas um "ouvinte"). Quando você sabe que há um ouvinte, a ação de retorno de chamada pode ser transmitida como um parâmetro construtor (e armazenada em um membro imutável!)
Ser capaz de compor funções (por exemplo, transformar
Action<T>
- se em apenas umAction
também é bastante útil em alguns cenários.Também devemos observar a sintaxe do Lambda aqui, porque você só obtém a sintaxe do Lambda quando promove funções para tipos de primeira classe. A sintaxe do Lambda pode ser muito expressiva e concisa.
Mônadas
É certo que este é meu ponto fraco, mas meu entendimento é que os fluxos de trabalho computacionais em F #, como o
async
fluxo de trabalho, são uma mônada. Essa é uma construção sutil, mas muito poderosa. É tão poderoso quanto ayield
palavra - chave usada para criarIEnumerable
classes em C #. Essencialmente, está construindo uma máquina de estado para você, mas sua lógica parece linear.Avaliação e Recursão Preguiçosas
Eu os reuni porque, embora eles sempre estejam agrupados como recursos de programação funcional, eles foram criados tão rapidamente em linguagens imperativas que é difícil chamá-las de funcionais.
Expressões S
Acho que não tenho certeza de onde colocar isso, mas a capacidade de tratar o código não compilado como um objeto (e inspecionar / modificá-lo), como Lisp S-Expressions ou LINQ Expressions, é, de certa forma, a ferramenta mais poderosa de programação funcional. A maioria das novas interfaces "fluentes" do .NET e DSLs usam uma combinação de sintaxe lambda e expressões LINQ para criar algumas APIs muito concisas. Sem mencionar Linq2Sql / Linq2Nhibernate onde seu código C # é "magicamente" executado como SQL em vez de como código C #.
Essa foi a resposta longa para a primeira parte da sua pergunta ... agora ...
A maior armadilha que enfrentei foi tentar encontrar a linha entre o uso de soluções funcionais e soluções imperativas. No entanto, depois de tentar as duas abordagens algumas vezes, você começa a ter uma ideia de que funcionará melhor.
Se você conhece o .NET, sugiro o F #. Por outro lado, se você estiver mais familiarizado com a JVM, sempre haverá o Clojure . Se você é mais acadêmico do que prático, então eu usaria o Common Lisp ou Scheme. Se você já conhece o Python, acredito que já existem muitas construções funcionais disponíveis lá.
fonte
Isso é verdade se você contar os programas desenvolvidos por programadores profissionais (ou pelo menos as pessoas que se veem como tal). Se você expandir sua rede para incluir programas desenvolvidos por pessoas que não se consideram como tal, o FP (ou pelo menos a programação em um estilo funcional) está bem próximo do OO (Excel, Mathematica, Matlab, R ... até mesmo o JavaScript 'moderno' )
Minha opinião pessoal é que o multicore não é o principal recurso do FP (pelo menos até os compiladores Haskell, Scala, Clojure, F # resolverem o problema de localidade do cache). A característica do assassino é
map
,filter
,fold
e amigos que permitem uma expressão mais sucinta de um grande grupo de algoritmos. Isso é composto pelas linguagens FP que possuem uma sintaxe mais concisa do que as versões OO mais populares.Além disso, o fato de o FP estar mais próximo do modelo relacional reduz a incompatibilidade de impedância com o RDBMS ... o que é - novamente pelo menos para os não programadores - muito bom.
Além disso, quando você tem dificuldades particularmente difíceis de satisfazer os requisitos de 'correção' - de uma forma que é difícil de testar (comum em computação científica / análise de grandes dados em que o objetivo é se tornar previamente desconhecido e, portanto, resultados inespecíficos), a FP pode oferecer vantagens.
Quantos de seus problemas podem ser resolvidos já saindo de bibliotecas / estruturas em qual plataforma (por exemplo, JVM ou .Net), quantas são novas? Existem construções de linguagem capazes de expressar esses problemas diretamente?
Quanto controle de baixo nível você precisa sobre o desempenho de espaço e tempo do seu aplicativo?
Quão rigorosos são os seus requisitos de "correção"?
Você pode se capacitar para treinar novamente os desenvolvedores e / ou competir com os benefícios oferecidos por alguns nichos altamente lucrativos no desenvolvimento de software?
fonte
Supondo que você seja um desenvolvedor C ++ / C # / Java no setor ...
Esteja preparado para colegas mal-humorados que não querem aprender nada. Esteja preparado para chefes de cabelos pontudos impondo más escolhas de linguagem "porque eles já foram codificadores". Esteja preparado para acadêmicos expressivos em fóruns patrocinando você sobre monóides. Esteja preparado para guerras intermináveis de idiomas, porque o Scala nem sequer tem eliminação de chamada de cauda e o Clojure realmente exige pedais para todos os suportes e não me inicie no Erlang.
Se você é um programador de web, a maior armadilha provavelmente será seu cabelo.
Eu começaria com a plataforma:
fonte
Para uma perspectiva (reconhecidamente tendenciosa) sobre essa questão, você pode conferir o blog de Bob Harper, Existential Type . Carnegie Mellon recentemente reformulou seu currículo de CS para ensinar programação funcional primeiro, com outros paradigmas sendo ensinados apenas quando uma base sólida em programação funcional foi estabelecida, e Harper está dando um golpe por golpe à medida que o novo currículo é implementado na prática. .
Harper é um dos principais desenvolvedores da linguagem de programação Standard ML, por isso é justo dizer que sua própria opinião sobre o assunto pode ser adivinhada com antecedência, e ele certamente não se esquiva de declarações controversas ao defender essa posição, mas ele faz o caso dele também.
fonte
var
ou qualquer coleção mutável uma única vez. Portanto, o pensamento imperativo é da OMI algum tipo de otimização prematura que, como todos sabemos, é a raiz de todo mal.Não existe uma fórmula mágica que diga quando usar a programação funcional. Não é como se a programação orientada a objetos fosse adequada para nossas situações atuais de programação. É apenas outra maneira de estruturar programas em termos de outro conjunto de abstrações.
A programação funcional não tem nada a ver com preguiça. ML e OCaml são linguagens funcionais e estritas. O maior obstáculo que você enfrentará é estruturar as coisas em termos de valores imutáveis e envolver sua mente em qualquer abstração usada no sistema de tipos para efeitos colaterais. As linguagens funcionais são mais adequadas para otimização devido ao fato de tornarem os efeitos colaterais muito explícitos no sistema de tipos. Haskell usa mônadas, mas existem outras abordagens para usar efeitos em linguagens funcionais puras. O Clean possui tipos de exclusividade e algumas outras linguagens no desenvolvimento têm outras coisas.
Entre as linguagens de programação que eu conheço, eu diria que apenas Haskell e Clean podem ser chamadas de linguagens funcionais. Todos os outros permitem efeitos colaterais sem explicitar esses efeitos no sistema de tipos. Então, se você vai dedicar tempo para aprender programação funcional, Haskell é provavelmente o único que se adequa à conta. Todos os outros que eu conheço, Erlang, Scala, Clojure etc. apenas fornecem abstrações funcionais sobre uma linguagem imperativa. Portanto, se você quiser abordar o paradigma funcional em bits, recomendo Scala ou Erlang e se você quiser resolver tudo de uma vez e possivelmente desistir de frustração, deve usar Haskell.
fonte
Eu atribuiria o aumento atual de interesses em linguagens funcionais ao fato de serem ideais para computação paralela. Por exemplo, toda a idéia de redução de mapa é baseada em paradigma funcional. E não há dúvida de que a computação paralela estará em alta, pois é claro que atualmente a expansão é muito mais fácil e barata do que a expansão. Mesmo no mercado consumidor, as CPUs obtêm mais núcleos, não mais GHz.
EDIT: uma vez que não é óbvio para todos.
Na programação funcional pura, uma função recebe entrada, produz saída e não tem efeitos colaterais. Não ter efeito colateral, significa que ele não possui estado compartilhado, portanto, não há necessidade de mecanismos de sincronização, que seriam necessários durante a execução simultânea. A sincronização é a parte mais difícil de qualquer software simultâneo / paralelo, tornando-o puramente funcional, você basicamente não precisa lidar com a parte mais difícil.
Quanto à redução de mapa, até o nome vem da programação funcional (tanto o mapeamento quanto a redução são operações típicas no paradigma funcional). As duas etapas de redução de mapa são funções que são executadas em paralelo, recebem entrada, produzem saída e não têm efeito colateral. Portanto, essa é exatamente a idéia pura de programação funcional.
Poucos exemplos de PF usados para paralelismo:
fonte