Usando geradores e lambda, podemos fazer programação funcional com Python. Você também pode conseguir a mesma coisa com Ruby.
Portanto, a pergunta é: por que precisamos de linguagens de programação funcional específicas, como Erlang, Haskell e Scheme? Existe algo diferente que essas linguagens de programação funcional específicas fornecem? Por que não podemos simplesmente usar o Python para programação funcional?
programming-languages
python
functional-programming
Joshua Partogi
fonte
fonte
Respostas:
Agradeço a pergunta, porque pessoalmente sou um grande fã do Python e do estilo funcional de programação. Eu tenho uma longa experiência em Python e comecei a aprender Haskell recentemente, então aqui estão alguns pontos baseados em minhas experiências pessoais sobre as diferenças entre essas linguagens também, de uma perspectiva funcional.
Pureza
Mesmo que você não se importe com a pureza das funções (isto é, sem causar efeitos colaterais) como um princípio, ele tem um efeito prático sobre a facilidade de ler o código e raciocinar sobre ele. Mesmo que você mantenha a pureza em suas próprias funções Python, há uma grande diferença em fazer o compilador impor a pureza e, acima de tudo, em ter a biblioteca padrão construída em termos de pureza e estruturas de dados imutáveis.
atuação
Você pode ou não se importar com o desempenho, dependendo do domínio do seu aplicativo, mas a digitação estática e a pureza garantida oferecem muito mais ao compilador, em comparação com o Python e outras linguagens dinâmicas (embora eu deva admitir que o PyPy está se saindo bem) incursões e, por exemplo, LuaJIT está à beira de milagres).
Otimização de chamada de cauda
Relacionado ao desempenho, mas um pouco diferente. Mesmo que você não se importe muito com o desempenho do tempo de execução, não ter a otimização de chamada de cauda (especialmente para recursão de cauda) limita as maneiras de implementar algoritmos no Python sem atingir os limites de pilha.
Sintaxe
Essa é a maior razão pela qual comecei a olhar para linguagens funcionais "reais" em vez de apenas usar Python com estilo funcional. Embora eu pense que o Python tenha uma sintaxe muito expressiva em geral, ele tem alguns pontos fracos específicos da codificação funcional. Por exemplo:
f = g . h
vs.f = lambda *arg: g(h(*arg))
f = map g
vs.f = functools.partial(map, g)
sum = reduce (+) lst
vs.sum = reduce(operator.add, lst)
y = func1 $ func2 $ func3 x
mais fácil de ler do quey = func1(func2(func3(x)))
quando você está familiarizado com essa notação.fonte
Estas são as diferenças mais importantes:
Haskell
Haskell e Erlang
Erlang
Esquema
Todas as línguas
Além disso, você deve dar uma olhada nas linguagens da família ML, como SML, Ocaml e F # e Scala, que fundem OO e programação funcional de uma nova maneira. Todos esses idiomas têm características interessantes únicas.
fonte
É difícil definir exatamente o que é uma "linguagem funcional" - fora dos idiomas que você listou, apenas Haskell é puramente funcional (todos os outros adotam algum tipo de abordagem híbrida). Porém, existem certos recursos de linguagem que são muito úteis para a programação funcional, e Ruby e Python não têm o suficiente para serem ambientes muito bons para FP. Aqui está minha lista de verificação pessoal, em ordem de importância:
A necessidade de (1) deve ser óbvia - funções de ordem superior são extremamente difíceis sem funções de primeira classe. Quando as pessoas falam que Ruby e Python são boas linguagens para FP, geralmente estão falando sobre isso. No entanto, esse recurso específico é necessário, mas não suficiente, para tornar uma linguagem boa para o FP.
(2) tem sido uma necessidade tradicional para o PF desde que o esquema foi inventado. Sem o TCO, é impossível programar com recursão profunda, que é uma das pedras angulares do FP, porque você sobrecarrega a pilha. A única linguagem "funcional" (por definição popular) que não possui isso é o Clojure (devido às limitações da JVM), mas o Clojure possui uma variedade de hacks para simular o TCO. (Para sua informação, o Ruby TCO é específico da implementação , mas o Python especificamente não o suporta .) O motivo pelo qual o TCO deve ser garantido é que, se for específico da implementação, as funções recursivas profundas serão interrompidas com algumas implementações, portanto você não pode realmente use-os de todo.
(3) é outra coisa importante que as linguagens funcionais modernas (especialmente Haskell, Erlang, Clojure e Scala) têm que Ruby e Python não têm. Sem entrar em muitos detalhes, a imutabilidade garantida elimina classes inteiras de bugs, especialmente em situações simultâneas, e permite coisas legais, como estruturas de dados persistentes . É muito difícil tirar proveito desses benefícios sem o suporte no nível do idioma.
(4) é, para mim, a coisa mais interessante sobre linguagens puramente funcionais (em oposição às linguagens híbridas). Considere a seguinte função Ruby extremamente simples:
Parece uma função pura, mas, devido à sobrecarga do operador, pode alterar o parâmetro ou causar efeitos colaterais, como a impressão no console. É improvável que alguém sobrecarregue o
+
operador para ter um efeito colateral, mas o idioma não oferece garantias. (O mesmo se aplica ao Python, embora talvez não com este exemplo específico.)Em uma linguagem puramente funcional, por outro lado, existem garantias no nível da linguagem de que as funções são referencialmente transparentes. Isso tem inúmeras vantagens: funções puras podem ser facilmente memorizadas; eles podem ser facilmente testados sem depender de qualquer tipo de estado global; e os valores dentro da função podem ser avaliados preguiçosamente ou em paralelo, sem se preocupar com problemas de simultaneidade. Haskell tira proveito disso, mas eu não sei o suficiente sobre outras linguagens funcionais para saber se elas o fazem.
Tudo isso dito, é possível usar técnicas de FP em quase qualquer linguagem (até Java). Por exemplo, o MapReduce do Google é inspirado em idéias funcionais, mas até onde eu sei, eles não usam nenhuma linguagem "funcional" para seus grandes projetos (acho que eles usam principalmente C ++, Java e Python).
fonte
Os idiomas que você menciona são muito diferentes.
Enquanto Python e Ruby são linguagens de tipo dinâmico, Haskell é estaticamente. Erlang é um idioma simultâneo, usa o modelo de ator e é muito diferente de todos os outros idiomas mencionados.
Python e Ruby têm muitas construções imperativas, enquanto em uma linguagem funcional mais pura como Haskell, tudo retorna algo ou, em outras palavras, tudo é uma função.
fonte
Tarde para a festa, como sempre, mas vou dizer as coisas de qualquer maneira.
Uma linguagem de programação funcional não é uma linguagem que permita a programação funcional. Se seguíssemos essa definição, praticamente qualquer linguagem em qualquer lugar é uma linguagem de programação funcional. (O mesmo se aplica a OOP, aliás. Você pode escrever em um estilo de OOP em C, se quiser. Portanto, de acordo com sua lógica, C é uma linguagem de OOP.)
O que torna uma linguagem de programação funcional não é o que permite programar, é o que permite programar com facilidade . Essa é a chave.
Portanto, o Python possui lambdas (que são casos incrivelmente anêmicos de fechamento) e oferece algumas funções de biblioteca que você verá nas bibliotecas funcionais, como "map" e "fold". Isso não é suficiente para torná-lo uma linguagem de programação funcional, no entanto, porque é difícil impossível programar consistentemente um estilo funcional adequado (e a linguagem certamente não impõe esse estilo!). Em sua essência, o Python é uma linguagem imperativa preocupada com operações de manipulação de estado e estado e isso está simplesmente em desacordo com a semântica de expressão e avaliação de expressão de uma linguagem funcional.
Então, por que temos linguagens de programação funcional quando Python (ou Ruby (ou insira a linguagem de sua escolha)) pode "fazer programação funcional"? Porque Python, et al não podem fazer a programação funcional adequada. É por isso.
fonte
Você pode fazer programação funcional em Java (consulte, por exemplo, http://functionaljava.org/ ). Você também pode fazer programação orientada a objetos em C . Simplesmente não é tão idiomático.
Portanto, não precisamos absolutamente de Erlang, Haskell, Scheme ou qualquer linguagem de programação específica, mas todos eles representam abordagens diferentes e trocas diferentes, tornando algumas tarefas mais fáceis e mais difíceis. O que você deve usar depende do que você deseja alcançar.
fonte
Esta questão pode ser aplicada a um número infinito de linguagens e paradigmas.
A maioria, se não todos os idiomas, existe por um motivo específico. Eles existem porque alguém tinha uma necessidade que nenhum idioma atual preencheu ou preencheu mal. (Isso obviamente não se aplica a todas as linguagens, mas eu sinto que se aplica à maioria das linguagens conhecidas.) Por exemplo, o python foi originalmente desenvolvido para interagir com o Amoeba OS [ 1 , 2 ] e Erlang foi criado para ajudar no desenvolvimento de aplicações de telefonia [ 3 ]. Então, uma resposta para a pergunta "Por que precisamos de outra linguagem funcional?" pode simplesmente ser, porque [insira o nome de alguém que sabe como projetar linguagens] não gostou da maneira como o python o fez.
Isso resume muito bem o que eu acho que é a resposta. Enquanto você pode fazer qualquer coisa com python que você pode fazer com uma linguagem funcional, você realmente gostaria? Tudo o que você pode fazer em C, você pode fazer em montagem, mas você gostaria? Diferentes idiomas sempre serão melhores em fazer coisas diferentes, e é assim que deve ser.
fonte
A programação funcional é tanto um paradigma de design quanto recursos de linguagem específicos. Ou, dito de outra forma, lambdas e uma função de mapa não produzem uma linguagem de programação funcional. Python e Ruby têm alguns recursos inspirados em linguagens de programação funcional, mas você ainda escreve código de uma maneira muito imperativa. (É como C: você pode escrever código semelhante ao OO em C, mas ninguém considera seriamente o C como uma linguagem OO.)
Veja: programação funcional não é apenas sobre lambdas, ou
map
funções de ordem superior. É sobre design . Um programa escrito em uma linguagem de programação funcional "verdadeira" resolve problemas através da composição de funções. Embora os programas escritos em Ruby ou Python possam usar recursos do tipo FP, eles geralmente não são lidos como um conjunto de funções compostas.fonte
Cada linguagem funcional que você mencionou se encaixa muito bem em um determinado nicho e os padrões idiomáticos que cada um incentiva os tornam muito adequados para determinadas tarefas que seriam impossíveis de realizar no Python, a menos que você construísse uma enorme biblioteca de módulos auxiliares. O mais óbvio de um desses nichos de excelência é o modelo de concorrência de Erlang. Os outros também têm pontos fortes semelhantes.
fonte
Todos os conceitos disponíveis no lambda-calculus, LISP e Scheme estão disponíveis no Python, portanto, sim, você pode fazer uma programação funcional nele. Se é conveniente ou não, é uma questão de contexto e bom gosto.
Você pode escrever facilmente um intérprete LISP (ou outra linguagem funcional) em Python (Ruby, Scala) (o que isso significa?). Você pode escrever um intérprete para Python usando puramente funcional, mas isso levaria muito trabalho. Até as linguagens "funcionais" são multiparadigmas hoje em dia.
Este livro antigo e bonito tem a maioria das respostas (embora não todas) sobre qual é a essência da programação funcional.
fonte
eval()
função, necessária para o código e os dados , mas vai além: permite modificar a maior parte do ambiente de tempo de execução, como no LISP.eval()
é uma metaprogramação em tempo de execução. Às vezes é útil, mas é extremamente caro. As macros Lisp são diferentes, é uma metaprogramação em tempo de compilação. Não está disponível no Python de nenhuma forma utilizável.Porque o Python também pode programar em um estilo não funcional, e isso não é bom o suficiente para o purista de FP. Porém, codificadores mais pragmáticos podem aproveitar os benefícios do estilo funcional sem serem dogmáticos:
- John Hughes, por que a programação funcional é importante
fonte
goto
é terrível.call-with-current-continuation
,.