Olá Habr! Apresento a você a tradução de um artigo de
Roman Provaznik -
Por que o FP importa mesmo para o desenvolvedor de OOP?Uma vez que eu estava muito interessado em programação funcional, comecei a estudá-lo e contar a todos os meus amigos como é maravilhoso. Mais tarde, me deparei com um artigo sobre programação funcional do ponto de vista de um programador OOP e decidi traduzi-lo para você. Não julgue estritamente, esta é minha primeira tradução.
Pediram-me para dar uma opinião pessoal sobre programação funcional de um ponto de vista objetivo. Fui até forçado a criar uma conta no Medium. Como um ex-desenvolvedor de POO e, no momento, um dia me tornarei um verdadeiro programador de FP, acho que tenho algo a dizer:
Bem-vindo viajante
Se você não passou os últimos 60 anos em outro planeta (se sim, seja bem-vindo, viajante), provavelmente já ouviu falar sobre programação funcional. Se você segue as tendências atuais da indústria de software, ouve diariamente termos como "programação funcional", "imutabilidade", "funções puras" e "composição". Tudo isso parece legal, agradável e compreensível até que você pense: "Ei, sou um programador de POO e não posso (ou não quero) mudar o paradigma. O que a programação funcional pode me dar? Por que eu deveria me preocupar? Como programador / entusiasta de FP que veio do mundo OOP, quero compartilhar o que eu mesmo gostaria de saber há muitos anos. Você pode falar sobre isso por horas, então vamos escolher as três coisas mais importantes.
Imutabilidade
A vantagem tradicional do FP é a palavra, que normalmente leva pelo menos dois slides de cada apresentação sobre programação funcional. Bala de prata FP, certo? Na verdade não. Apesar do fato de que essa palavra é mais frequentemente usada principalmente por programadores funcionais, ela não é exclusiva do FP. Como desenvolvedor de OOP, você pode atingir (quase) o mesmo nível de imutabilidade que um desenvolvedor de FP. Na verdade, isso é fácil, basta olhar de maneira um pouco diferente para seus objetos e coleções. Imagine que você não está alterando o original, mas criando uma nova versão. Item adicionado à coleção? Ótimo! Você não alterou a coleção original, apenas possui uma nova coleção contendo o item adicionado. Alterou a propriedade de um objeto? Uau! Agora você tem um novo objeto com uma propriedade alterada.
Eu sei, eu sei - parece estranho. Mas essa pequena mudança de consciência permitirá que você durma mais calmo. Assim que você entender que seus objetos não podem ser alterados (apenas copiados), você terá certeza de que ninguém na equipe poderá transferi-los para outro lugar. É como pegar emprestado sua cassete de áudio favorita do Pink Floyd antiga, sem medo de recuperá-la novamente com Justin Bieber. E como bônus, seu código terá métodos totalmente rastreáveis nos quais ocorrem mudanças reais (onde novos objetos são criados com base nos originais). E, quase esqueci que, se você é um desenvolvedor de C # ou Java, já os usa chamando “ToLower ()”, “Trim ()” em linhas inicialmente imutáveis. Isso não é essencialmente novidade.
Funções puras
Outra frase da moda equivocadamente considerada exclusivamente FP. O que é uma "função pura"? Simplificando, uma função pura é uma função que retorna o mesmo resultado com o mesmo valor de entrada, sem comunicação com o “mundo externo” (operações de E / S, status geral, etc.), também conhecido como “efeitos colaterais”. Um exemplo típico desse tipo de função pode ser obter o comprimento da string (você não se conectará ao banco de dados para contar o número de caracteres em uma string?), Calcular o seno e assim por diante. Quais são os benefícios disso para OOP? O mesmo que para FP. Se você trabalha com funções puras (ou métodos), sabe exatamente qual resultado obterá para cada valor de entrada. E se o seu código não depender de algum estado oculto, é muito fácil testar e você não se preocupará em escrever um teste de unidade. Todos sabemos que, sem interagir com o mundo exterior, nosso software seria inútil, mas há uma diferença notável entre código puro (escrito com funções / métodos puros) com entrada e saída apenas nas bordas do sistema e um sistema no qual cada método depende do estado interno, atualizado por outros métodos.
Mais uma vez, um pouco de repensar a abordagem de E / S oferece todas as vantagens do FP, além do teste se tornar tão simples que finalmente começará a trazer prazer.
Declarativo VS Imperativo
Já mudamos o ponto de vista do nosso código - podemos escrever um código mais seguro (imutável) e testável (limpo). Agora é hora de ir um pouco mais longe e mudar a abordagem para determinar o que nosso software deve fazer. O que mais faz OOP tão diferente de AF? Em um mundo funcional, definimos "o que" deve acontecer em vez de determinar "como" deve acontecer. Obviamente, resta a parte do programa que executa essa operação específica, mas é importante se concentrar em expressões em vez de em instruções. E é isso que você pode fazer no seu idioma favorito de POO.
Por exemplo, se você estiver familiarizado com coisas como LINQ (de C #), já conhece os benefícios das expressões de consulta quando pode ler seu código como “Sim, aqui eu peguei 10 itens da coleção, classifique-os em ordem alfabética e use-os como parâmetro para os seguintes itens método ". Você provavelmente já leu milhares de expressões do tipo LINQ sem ter que pensar no que realmente está acontecendo nos bastidores. E o mais importante é se concentrar no que realmente importa.
Sumário
Eu acho que é o suficiente por enquanto. Eu não quero acabar vendendo FP como uma bala de prata. O mundo não é apenas preto e branco. A verdade é que FP é incrivelmente difícil para mim. Quase tão complicado quanto o POO adequado. Mas definitivamente vale a pena tentar. Do meu ponto de vista, OOP vs FP é, em geral, a maneira como penso sobre o código e sua estrutura. Como penso em dependências, efeitos colaterais, todo o mundo de E / S e testes. Para resumir com um pensamento, "uma abordagem funcional ajudará, independentemente do idioma, área de assunto e plataforma".