Javascript é uma linguagem de programação funcional

34
  • Javascript é uma linguagem funcional? Eu sei que ele tem objetos e você também pode fazer POO com ele, mas também é uma linguagem funcional, pode ser usada dessa maneira?
  • Você sabe como o OOP se tornou / parece a próxima evolução na programação, isso significa que 'Programação Funcional' é a próxima evolução (Nota: este NÃO é um pedido de opinião, mas um pedido de resposta factual baseada em evidências, e esta nota é mais para os moderadores do que para os colaboradores;)).
  • Eu aprendo melhor através de exemplos, talvez alguém possa mostrar executando a mesma tarefa de uma maneira OOP e depois de uma maneira de Programação Funcional para eu entender e comparar o que a programação funcional faz / é.

Eu realmente não entendo completamente 'Programação Funcional' para ser honesto: P Então, comparar o Javascript com a programação funcional pode ser totalmente incorreto.

Para colocar a programação funcional em termos leigos: é simplesmente o benefício da abstração através do uso de funções anônimas?

Ou isso é simples demais? De uma maneira simples, OOP é o benefício da abstração através de objetos, mas acredito que seja um pouco simplista demais para descrever o OOP.

Este é um bom exemplo de programação funcional? ...

Exemplo de Javascript OOP:

// sum some numbers
function Number( v )
{ 
  this.val = v;
}

Number.prototype.add( /*Number*/ n2 )
{
    this.val += n2.val;
}

Exemplo de programação funcional:

function forEach(array, action) 
{
   for (var i = 0; i < array.length; i++)
       action(array[i]);
}  

function add(array)
{
    var i=0;
    forEach(array, function(n)
    {
        i += n;
    });
    return i;
}

var res = add([1,9]);
Marek
fonte
Depende da definição de "linguagem de programação funcional". Em um sentido amplo, pode ser entendida como a capacidade de criar valores funcionais com valores fechados, ou seja, como ter uma construção "lambda" (no sentido do cálculo lambda) e, em seguida, o Javascript se ajusta à conta.
Basile Starynkevitch
2
Or is that way too simple?Sim, é. Às vezes, funções anônimas são associadas a linguagens funcionais e linguagens multiparadigma que favorecem a programação funcional, mas não são uma característica exclusiva das linguagens funcionais. Mas se você vê-los como uma implementação do λ-cálculo, bem, eles são uma parte essencial da programação funcional, o principal ponto é que não é tão simples :)
yannis
O design do Javascript impede que as implementações possam otimizar a chamada de cauda. Nos meus livros, isso por si só impede que seja rotulado como funcional.
dan_waterworth
I know it has objects & you can do OOP with it alsoNão, você não pode. É uma programação baseada em protótipos que elimina a distinção entre classe e objeto. Pessoalmente, considero que a programação baseada em protótipo é falha nesse nível básico.
RokL
Javascript não é uma linguagem funcional, com certeza possui características funcionais, mas o bom e velho imperativo C, na verdade, toda linguagem possui características funcionais básicas. Uma linguagem funcional pura, como Haskell, ML, etc, é uma linguagem declarativa, não imperativa.
ALXGTV

Respostas:

72

Javascript é uma linguagem funcional? Eu sei que ele tem objetos e você também pode fazer POO com ele, mas também é uma linguagem funcional, pode ser usada dessa maneira?

Às vezes, as pessoas dizem programação funcional, quando o que elas querem dizer é programação imperativa ou programação procedural . A rigor, a programação funcional é:

Na ciência da computação, a programação funcional é um paradigma de programação que trata a computação como a avaliação de funções matemáticas e evita dados de estado e mutáveis . Ele enfatiza a aplicação de funções, em contraste com o estilo de programação imperativa, que enfatiza as mudanças de estado. A programação funcional tem suas raízes no cálculo lambda, um sistema formal desenvolvido na década de 1930 para investigar a definição de funções, aplicação de funções e recursão. Muitas linguagens de programação funcional podem ser vistas como elaborações no cálculo lambda.

Embora o Javascript não seja amplamente conhecido ou usado como uma linguagem funcional, ele possui alguns elementos funcionais :

JavaScript tem muito em comum com o Scheme. É uma linguagem dinâmica. Possui um tipo de dados flexível (matrizes) que pode simular facilmente expressões s. E o mais importante, as funções são lambdas.

O esquema é um dialeto do Lisp , e provavelmente uma das linguagens que a maioria dos programadores pensa quando discutem programação funcional. Quando se trata de orientação a objetos , o Javascript é uma linguagem orientada a objetos. Mas sua orientação a objetos é baseada em protótipo :

A programação baseada em protótipo é um estilo de programação orientada a objetos em que as classes não estão presentes, e a reutilização do comportamento (conhecida como herança em linguagens baseadas em classes) é realizada por meio de um processo de clonagem de objetos existentes que servem como protótipos. Esse modelo também pode ser conhecido como programação sem classe, orientada a protótipo ou baseada em instância. Delegação é o recurso de linguagem que suporta programação baseada em protótipo.

Portanto, embora o Javascript seja orientado a objetos, ele não segue o modelo baseado em classe mais comum , assim como linguagens como C ++, C #, Java e PHP (e várias outras). E é claro que também é uma linguagem imperativa, o que leva à confusão com a programação funcional que descrevi acima.

Você sabe como o OOP se tornou / parece a próxima evolução na programação, isso significa que 'Programação Funcional' é a próxima evolução

Orientação a objetos e programação funcional são apenas dois dos muitos paradigmas de programação diferentes , são estilos diferentes de programação com diferentes conceitos e abstrações. A palavra-chave é "diferente". Não existe um único paradigma que seja melhor que outros ou mais evoluído que outros; cada um se encaixa em alguns cenários melhor que os outros. Alguns podem ter uma origem bem mais antiga que outros, mas em termos evolutivos os tornam melhores, pois sobreviveram por mais tempo. Mas essa não é uma maneira muito inteligente de ver isso.

Javascript, como descrevi acima e em várias outras línguas, é multiparadigma. Ele permite que você escreva código em estilo imperativo, orientado a objeto e funcional, baseado em protótipo. Cabe a você escolher qual melhor se adequa ao que você está construindo. Existem também várias linguagens de paradigma único, o exemplo canônico é Java, que permite apenas a programação orientada a objetos baseada em classe 1 .

Você realmente deve resistir a qualquer desejo de tratar linguagens e paradigmas como declarações de moda. Há um monte de porcaria por aí, a maioria escrita por fanboys / fangirls ou pessoas de marketing, com pouco (se houver) conhecimento e entendimento de programação. Termos como "melhor", "mais evoluído" etc. simplesmente não se aplicam.

Eu aprendo melhor através de exemplos, talvez alguém possa mostrar executando a mesma tarefa de uma maneira OOP e depois de uma maneira de Programação Funcional para eu entender e comparar o que a programação funcional faz / é.

Essa seria uma maneira terrível de aprender. A orientação funcional e do objeto são estilos bem diferentes, e qualquer exemplo que não seja terrivelmente simples não se encaixaria em um ou outro estilo.

1 Mas ultimamente tenta expandir seu escopo para programação genérica, vamos ver como isso acontece.


Em conclusão:

  • Concentre-se em aprender Javascript, é uma linguagem bonita e extremamente útil. Aprenda o idioma, não o hype.
  • Alguns paradigmas diferentes, todos igualmente úteis. Você escolhe qual prefere e qual se encaixa melhor no que estiver construindo.
  • Se você deseja aprender programação funcional, escolha uma linguagem mais adequada, como Scheme ou Clojure . Mas primeiro você precisa entender os conceitos matemáticos envolvidos.
  • Faça alguma pesquisa antes de perguntar. A maioria das suas perguntas é respondida pelos artigos relevantes da Wikipedia. Saber pesquisar e pedir é uma habilidade extremamente importante para qualquer programador.
yannis
fonte
5
+1 Ótima resposta. Devido à maneira como a educação em programação é estruturada, novos codificadores parecem pensar que os paradigmas são exclusivos e discretos, mas não são. Tente escrever código OOP que tire proveito dos conceitos funcionais quando fizer sentido. A programação orientada a eventos é um paradigma, mas os aspectos da EDP certamente influenciam todos os programas da Web e da GUI. O polimorfismo , um recurso essencial do OOP, é realmente uma programação genérica. Nomear essas idéias nos ajuda a conceber uma boa programação, mas você não deve usar uma para excluir outras.
Kojiro
Embora a pergunta original e sua resposta estejam descrevendo Javascript e estejam relacionadas à programação funcional, acho que sua resposta é uma das melhores comparações entre OO e programação funcional que eu já vi. Bem feito.
AnotherDeveloper
“Isso seria uma maneira terrível de aprender.” Acabei de ler este livro que apresenta um problema e o resolve com uma variedade de paradigmas, incluindo estilos de OOP e FP: github.com/crista/exercises-in-programming-style . Eu aprendi muito com isso!
Nick
@ Nick Isso só pode descrever para você como é o paradigma e como ele funciona, mas não informa o porquê , o que sem dúvida é o aspecto mais importante. Mas você precisa aprender como antes de saber o porquê :) às vezes esquecemos que essas coisas são um processo.
Matthew Brent
8

Javascript pode ser usado como uma linguagem funcional, na verdade, ele faz muito bem. É possível implementar mônadas que suportam uma construção lambda, etc. Não é exclusivamente uma linguagem funcional, pois também possui muitos recursos orientados a objetos, mas pode ser usada dessa maneira. Na verdade, acho que usar o Javascript como uma linguagem funcional é uma ótima maneira de usá-lo. (Exemplo jQuery e underscore.js)

Zachary K
fonte
bom e conciso! Concordou que a programação funcional é frequentemente a maneira mais fácil de fazer algo em js.
bunglestink
Ainda mais interessante que as mônadas, você pode implementar setas é JS ( cs.umd.edu/projects/PL/arrowlets ). Agora, por que alguém iria querer flechas em JavaScript, essa é uma questão em aberto. Mas isto pode ser feito.
Rtperson
Admito que não entendo o suficiente sobre flechas para saber se elas serão úteis. Mas eu estou trabalhando em um livro sobre mônadas em Javascript e posso adicionar um capítulo sobre as setas ( shop.oreilly.com/product/0636920023890.do )
Zachary K
6

Evolução normalmente significa uma mudança incremental . OOP não é uma adição incremental à programação procedural - na verdade, é inteiramente ortogonal a um modelo de programação subjacente e pode ser combinado com qualquer um deles. A programação funcional não é uma adição incremental ao procedimento, OOP ou o que quer que seja - é uma base alternativa para expressar os princípios fundamentais da computação, e é realmente a primeira dessas bases já formuladas, muito antes dos primeiros computadores aparecerem. É importante entender que todos esses sistemas fundamentais são equivalentes (isto é, um pode ser expresso em termos de outro).

Para entender a abordagem funcional, você precisará obter a matemática básica primeiro. Se você quiser ter uma idéia do que significa codificar em estilo funcional em Javascript, comece a usar o jQuery .

SK-logic
fonte
2

Não.

JavaScript é uma linguagem orientada a objetos em primeiro lugar.

Isso não quer dizer que você não possa escrever programas JavaScript em um estilo funcional, pois é possível adotar um estilo funcional em qualquer linguagem completa do Turing se você se esforçar o suficiente. Você pode fazer a programação funcional no assembler, se quiser. Mas isso não torna todos os idiomas funcionais. Você também pode chamar Haskell de imperativo ou Java uma linguagem de programação lógica - se você adotasse essa abordagem, os termos logo se tornariam sem sentido.

Na IMO, a maneira de classificar um idioma no paradigma apropriado é considerar:

  • Qual é o estilo dominante ativado pelas construções de linguagem (claramente OOP para JavaScript, linguagens funcionais enfatizam funções e valores de dados imutáveis)
  • Que paradigma é suportado nas principais bibliotecas da linguagem (novamente claramente OOP para JavaScript)
  • Quais recursos estão desabilitados ou desencorajados no idioma (os idiomas funcionais desencorajam ou proíbem variáveis ​​mutáveis, o que não é o caso do JavaScript)
  • Qual estilo de desenvolvimento prevalece na comunidade de desenvolvedores que usam a linguagem (novamente, OOP é claramente predominante no mundo JavaScript)

Pessoalmente, acho bastante divertido que muitas pessoas gostem de afirmar que um idioma é "funcional" apenas porque é um termo moderno no momento :-)

Se você quer uma perspectiva um pouco longa, mas divertida, sobre os paradigmas de programação ao longo dos anos, vale a pena assistir ao vídeo "A Última Linguagem de Programação" do tio Bob Martin . Para mim, o grande insight dessa palestra foi que os paradigmas de programação são definidos por quais recursos eles tiram , e não pelos recursos que colocam ......

Mikera
fonte
What is the dominant style enabled by the language constructsEu desafio você a tentar aplicar isso a Perl ... Ou qualquer outro dos seus pontos, realmente :)
yannis
2
Perl? Bom desafio! É uma linguagem parecida com assembly, no sentido de que você pode hackear praticamente qualquer paradigma que desejar juntos, mas no uso comum que eu vi (scripts) é usado principalmente como uma linguagem imperativa / processual.
Mikera
Bem, oop também é bastante comum. De uma maneira perversa, é claro. E funcional também , embora incomum. perl é apenas perl, não há sentido em tentar fazer sentido fora dele :)
yannis
O JavaScript é um pouco mais funcional que o Java, porque pelo menos possui encerramentos e funções de primeira classe. Mas você está certo, o JavaScript é tão funcional quanto o C #.
Raynos
2

O Javascript é o primeiro protótipo, com recursos funcionais - concedidos pelo uso de funções como objetos de primeira classe.

Isso significa que você pode usar funções como dados, o que tem o efeito curioso de reduzir a necessidade de variáveis ​​que mantêm o estado. Se você achar que está buscando a instrução var ou estiver usando uma ou mais instruções "if", estará se afastando de um estilo funcional.

Outra idiossincrasia notável do estilo funcional é que as funções SOMENTE retornam o resultado de sua avaliação e não têm efeitos colaterais no estado fora de seu escopo:

// oops, this is producing a side effect
function sideEffecter(){//theres no input...        
    window.thingy = 'foo';
    // hey, this isn't returning anything!!!
} 

Linguagens funcionais são não destrutivas - o que significa que elas não modificam a entrada, mas retornam dados inteiramente novos com base na entrada. Veja este tópico: https://stackoverflow.com/questions/749084/jquery-map-vs-each

Os idiomas funcionais também apresentam muitos métodos em comum - com nomes como "mapa", "dobra", "redução" que processam listas / coleções. No JS, diferentemente de outras linguagens, temos que criá-las manualmente - veja bibliotecas como underscore.js para alguns exemplos, embora a implementação mais recente da JS contenha algumas delas diretamente.

O importante a ter em mente (IMO) é que, embora o JS possa utilizar alguns padrões funcionais, ele nem sempre está bem equipado para ser executado.

Veja a iteração sobre uma matriz, por exemplo. Você pode fazer isso usando um estilo funcional ou as construções de loop nativas - e, geralmente, o loop é mais eficiente. Veja este exemplo - clique nele com loops de tamanho crescente e registre os tempos de execução em diferentes navegadores (eu já fiz isso, mas perdi os benchmarks - desculpe!):

var test = ['foo', 'bar', 'baz'], removeFunc, removeLoop;

//(semi)functional style...
// to be really functional each condition in the ternary would be another function
removeFunc = function(src, trg) {
    return src.length === 0 ? 
        src : 
            src[0] === trg ? 
                src.slice(1) : 
                    [src[0]].concat(removeFunc(src.slice(1), trg));
};

//but this is faster
removeLoop = function(src, trg){
    var len = src.length, // using variables to represent state...
        i=0, 
        result = [];        
    while(i < n){
       if(src[i] !== trg){
          result.push(src[i]);
       }
       i = i+1;
    }
}

Além disso, se você usar uma construção funcional para atingir loops de tamanho considerável e não utilizar alguma forma de gerenciamento ad-hoc da pilha, poderá inundar a pilha (embora, para ser justo, você precise de uma lista GRANDE para que isso ocorra. ..) Você também precisa incluir as otimizações de variantes em cada navegador - embora se você estiver trabalhando em um ambiente Node.js. isso é obviamente mais um destino fixo.

Isso não quer dizer que você não deve usar construções funcionais em Javascript - apenas esteja ciente das limitações na implementação em relação ao ambiente.

Aqui estão alguns links que podem ser do seu interesse:

Um bom capítulo sobre Programação Funcional em Javascript, do excelente "Javascript Eloquent"

The Little Schemer

um amigo meu escreveu uma biblioteca JS baseada no Little Schemer

Um bom tutorial sobre o esquema que pode ajudá-lo a compreender melhor o FP

sunwukung
fonte