Aprender uma linguagem funcional torna um programador de POO melhor? [fechadas]

28

Como programador Java / C # / C ++, ouço muita conversa sobre linguagens funcionais, mas nunca achei necessário aprender uma. Também ouvi dizer que o nível mais alto de pensamento introduzido nas linguagens funcionais faz de você um melhor programador de OOP / linguagem processual.

alguém pode confirmar isso? De que maneira isso melhora suas habilidades de programação?

Qual é uma boa escolha de idioma para aprender com o objetivo de melhorar as habilidades em um idioma menos sofisticado?

GavinH
fonte
3
Se você está codificando em C #, já conhece um. LINQ é uma coisa bastante funcional.
SK-logic,
Eu acho que OOP é melhor para modelar objetos da vida real.
Tulains Córdova
1
@ user61852 A maioria dos padrões de design de OO não modela nada sobre objetos da "vida real", mas na verdade conceitos altamente abstratos.
Andres F.
Seja mais que um programador Java / C # (+ C ++). Há uma diferença entre um canivete suíço gigantesco com um panfleto não tão pequeno que descreve por que você selecionaria a lâmina X de 40 e uma lâmina que você pode esculpir muito perto de qualquer coisa que você queira, porque é afiado e curvas. certo, de modo que você possa aplicar seu poder de corte a uma ampla variedade de circunstâncias sem pensar muito. (com um saca-rolhas no identificador de curso)
Erik Reppen

Respostas:

32

Eu basicamente concordo com a resposta de FrustratedWithFormsDesign , mas você também perguntou como aprender o novo paradigma ajuda a desenvolver as habilidades de alguém. Eu posso dar alguns exemplos da minha própria experiência.

Desde que aprendi programação funcional, sou muito mais consciente sobre quais conceitos com os quais trabalho são mais naturalmente considerados "objetos" (geralmente onde a mutação faz sentido) e quais são mais naturalmente considerados "valores" imutáveis ​​(acho que há uma distinção importante , tocando em onde OO faz sentido vs. quando FP faz sentido, mas essa é apenas a minha opinião).

Percebo onde meu código inclui efeitos colaterais e sou mais cuidadoso em isolar esses locais, tornando mais funções "puras" minhas funções. Isso melhora muito a testabilidade do meu código OO.

Estou mais consciente dos ciclos na minha representação de dados. (Por exemplo, eu não acho que você possa escrever uma função para converter uma lista vinculada em uma lista duplamente vinculada em Haskell, para que você observe ciclos muito mais nesse idioma.) Evitar ciclos reduz a quantidade de sincronização você precisa executar para que suas estruturas de dados sejam internamente consistentes, facilitando a carga no compartilhamento dessas estruturas entre os encadeamentos.

É mais provável que eu recorra à recursão (as construções de loop recursivo do esquema são coisas bonitas). Dijkstra abordou a importância disso em Notas sobre programação estruturada - algoritmos recursivos mapeiam muito diretamente a indução matemática, o que ele sugere ser o único meio de provar intelectualmente que nossos loops estão corretos. (Não sugiro que devemos provar que nosso código está correto, mas que, quanto mais fácil formos fazê-lo, maior a probabilidade de que nosso código esteja correto.)

É mais provável que eu use funções de ordem superior. Artigo de John Hughes, Por que a Programação Funcional é Importante . Ele enfatiza a composibilidade que você obtém ao empregar técnicas de programação funcional, com funções de ordem superior desempenhando um papel importante.

Além disso, conforme abordado na resposta de Jetti , você verá que muitas idéias de FP estão sendo incorporadas em novas linguagens OO. Ruby e Python fornecem muitas funções de ordem superior. Ouvi o LINQ ser descrito como uma tentativa de trazer suporte para compreensão monádica no C #, mesmo o C ++ agora tem expressões lambda.

Aidan Cully
fonte
@Aidan: wrt lambdas em C ++ 0x, pelo menos os novos compiladores C ++ já os incorporaram.
Matthieu M.
1
"Objeto" como "coisa que mantém um estado mutável" é muito comum, mas o padrão Objeto de Valor existe há muitos anos.
9758 Frank Shearar
@ Matthieu, obrigado, atualizei o texto para refletir isso.
10248115Data de publicação
@ Frank: obrigado pelo ponteiro. Não incluí isso na resposta, mas a principal objeção que tenho de transformar Valores em objetos tem a ver com a distinção entre interfaces de objetos em preto e branco (que pertencem a objetos) e operações (nas quais os relacionamentos entre objetos são mais primário do que os próprios objetos). 1 + 2é matematicamente equivalente a 2 + 1, mas 1.+(2)é implementado de maneira diferente de 2.+(1). Existem vários problemas de SW que podem ser entendidos mais naturalmente usando operações do que usando interfaces de objeto.
10248115Data
1
@Aidan Você leu "Sobre a compreensão da abstração de dados, revisitada", de William Cook? Ele investiga as diferenças entre objetos e ADTs, que é o que você está sugerindo.
Frank Shearar
32

Eu não diria que é garantido que você será um programador de POO melhor, mas ele apresentará uma nova maneira de pensar, e isso pode torná-lo melhor na solução de problemas em geral, não apenas em termos de POO.

FrustratedWithFormsDesigner
fonte
3
Dado que os objetos são, na verdade, funções de ordem superior, descobri que aprender coisas sobre FP ajudou diretamente com o meu POO. É, como você diz, mais geralmente aplicável / útil.
Frank Shearar
12

Aprender uma linguagem funcional - Lisp para mim - realmente ajuda na criação de aplicativos paralelos. Os métodos funcionais (com base no estado, sem efeitos colaterais) são muito mais fáceis de sincronizar e tornam o thread seguro, pois dependem apenas de suas entradas. Isso significa que os únicos dados que você precisa observar para uma determinada área de código são os parâmetros que você passa. Isso também facilita a depuração.

Michael K
fonte
Você descobrirá que também ajuda com as bibliotecas de segmentação, que tendem a esperar funções puras como tarefas. Também pode ajudar indiretamente, há lugares em que escreverei código OO em uma espécie de "estilo funcional" em que há um "parâmetro proprietário" que possui um bloqueio implícito em vários objetos aos quais ele faz referência e são usados ​​pela função . Contanto que você documente suas expectativas (e as teste de unidade), isso poderá fornecer um código multithread melhor com poucos problemas de bloqueio. E alguns bloqueios explícitos.
Nunca ouvi falar do Prolog ser chamado de linguagem funcional. Se eu apertar os olhos o bastante, posso ver vagamente como (partes de) o Prolog poderia ajudar com o FP.
Frank Shearar
1
Prolog não é uma linguagem funcional. É uma linguagem lógica. Se você deseja uma linguagem lógica do tipo Prolog que também esteja integrada à programação funcional, lembre-se de experimentar o Mercury . Aviso: Isso machucará seu cérebro um pouco, mesmo que você já conheça o Prolog.
APENAS MINHA OPINIÃO correta
@ APENAS MINHA OPINIÃO correta: Sim, acho que você está certo. Acho que preciso aprender mais sobre linguagens funcionais!
Michael K
1
@moz: Sim, eu gostaria que o Java tivesse lambdas. ThreadObjetos anônimos são ... desajeitados.
Michael K
9

Aprender qualquer outro paradigma de programação melhorará suas habilidades de programação em geral. A programação, quando não é um material acadêmico de nível de pesquisa (e mesmo assim, frequentemente), é basicamente a solução de problemas. Pensando, em uma palavra. Os vários paradigmas são diferentes maneiras de pensar sobre os problemas e suas soluções. Portanto, não pense nisso como "aprender uma linguagem funcional". Pense nisso como "aprender uma maneira diferente de pensar sobre os problemas e suas soluções". Então você verá os benefícios de aprender um idioma, mesmo que nunca o use.

Para resolver sua pergunta específica, eu era um programador de C ++ nos dias de antigamente (antes de existir um padrão para C ++). Eu segui todas as coisas usuais com objetos que mantinham o estado manipulado por métodos, etc. etc. etc. (Acho que ninguém realmente aprende Haskell.) O exercício parecia um pouco desperdiçado na época, até que um dos meus colegas, o testador designado para o meu grupo, fez um comentário imediato de que meu código estava ficando mais fácil de testar.

O que aconteceu foi que eu comecei a tornar meus objetos cada vez mais imutáveis. Classes com estado mutável complexo começaram a ser substituídas por classes que se clonavam com alterações, retornando os novos objetos. Os objetos compartilhados começaram a ser substituídos por objetos que tinham semântica de copiar na gravação (dando assim a ilusão de muitos clones de objetos sem sobrecarga de memória). As funções não tinham efeitos colaterais, a menos que fosse absolutamente necessário; a pura definição matemática de "função" era cada vez mais a norma. Tudo isso começou a acontecer no meu código naturalmente - nenhum pensamento consciente se envolveu - enquanto eu explorava cada vez mais o espaço de programação funcional.

Agora, tenho como objetivo aprender pelo menos um novo paradigma de programação a cada dois anos (mesmo que seja apenas um pequeno paradigma de extensão como AOP) e pelo menos duas novas linguagens dentro de cada paradigma (um o mais puro possível, um mais híbrido / prático ) Cada um me deu novas ferramentas intelectuais para aplicar a toda a minha programação em qualquer idioma, portanto, o tempo gasto aprendendo-as não foi, na minha opinião, desperdiçado nem um pouco.

APENAS MINHA OPINIÃO correta
fonte
3

Eu já disse isso antes e direi novamente, o aprendizado de linguagens funcionais definitivamente melhorou meu C #. Isso me ajudou a entender as lambdas (e me ajudou a amá-las). Também me fez perceber o quanto eu prefiro programação funcional (F #) ao trabalhar com operações assíncronas!

Jetti
fonte
3

O código da máquina nada mais é do que uma lista de efeitos colaterais - comandos que são executados diretamente pelo processador. Os efeitos colaterais em C são diferentes. Em vez de manipular os registradores e o hardware físico, você lida com um conjunto de abstrações e deixa o compilador fazer todo o trabalho sujo. C também permite estruturar seus efeitos colaterais em loops e instruções if then. O C ++ aprimora o C adicionando OOP e alguns recursos muito necessários ao idioma. Java e C # adicionam coleta de lixo e Python adiciona digitação dinâmica.

Mesmo com todos esses recursos - digitação dinâmica, coleta de lixo, etc., os programas nessas linguagens ainda são inteiramente baseados em efeitos colaterais. Linguagens de programação funcional, como Scheme, Clojure, Haskell e ML, são algo completamente diferente; essas linguagens estão mais próximas da matemática do que do código de máquina. Em vez de usar efeitos colaterais, você transmite valores em torno de funções.

Qual é uma boa escolha de idioma para aprender com o objetivo de melhorar as habilidades em um idioma menos sofisticado?

Eu recomendo o Scheme , é mínimo e foi usado nas antigas classes de programação introdutória do MIT. As outras linguagens de programação funcional são muito mais difíceis de aprender. Clojure traz consigo todos os meandros do Java, o ML traz um complicado sistema de tipo estático, o Haskell às vezes é chamado de linguagem acadêmica - não é ideal para iniciantes e assim por diante. O esquema, por outro lado, é fácil de aprender e entender.

De que maneira isso melhora suas habilidades de programação?

Quase todas as linguagens de programação de alto nível têm funções e recursão - os conceitos sobre os quais a programação funcional se baseia. Como tal, seu conhecimento de FP deve ser útil em quase todos os lugares, no entanto, se você realmente deseja programar funcionalmente, deve usar uma linguagem em que seja natural e eficiente, em vez de tentar adaptar o design de linguagem de outra pessoa ao seu gosto, ou seja, você deve usar uma linguagem de programação funcional para fazer a programação funcional.

jhuni
fonte