Javascript est-il un langage de programmation fonctionnel?

34
  • Javascript est-il un langage fonctionnel? Je sais qu'il a des objets et que vous pouvez aussi faire de la programmation orientée objet, mais est-ce aussi un langage fonctionnel, peut-il être utilisé de cette manière?
  • Vous savez comment la programmation orientée objet est devenue / semble être la prochaine évolution de la programmation. Cela signifie-t-il que la «programmation fonctionnelle» constitue la prochaine évolution (Remarque: ceci n'est PAS une invite à une opinion plus pour les modérateurs que pour les contributeurs;)).
  • J'apprends mieux par des exemples. Peut-être que quelqu'un pourrait montrer qu'il exécute la même tâche de manière POO, puis de manière programmée, pour comprendre et comparer ce que la programmation fonctionnelle fait / est.

Pour être honnête, je ne comprends pas vraiment bien la «programmation fonctionnelle»: P Ainsi, comparer le code Javascript à la programmation fonctionnelle peut être totalement incorrect.

En termes simples, la programmation fonctionnelle est-elle simplement le bénéfice de l'abstration PAR l'utilisation de fonctions anonymes?

Ou est-ce trop simple? De manière simple, la POO représente l'avantage de l'abstraction à travers des objets, mais je pense que c'est un peu trop simpliste pour décrire la POO.

Est-ce un bon exemple de programmation fonctionnelle? ...

Exemple de POO Javascript:

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

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

Exemple de programmation fonctionnelle:

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
la source
Cela dépend de la définition de "langage de programmation fonctionnel". Au sens large, cela peut être compris comme l'aptitude à construire des valeurs fonctionnelles avec des valeurs fermées, c'est-à-dire comme ayant une construction "lambda" (au sens du lambda-calcul), puis que Javascript convient parfaitement.
Basile Starynkevitch
2
Or is that way too simple?Oui, c'est ça. Les fonctions anonymes sont parfois associées à des langages fonctionnels et à des langages à paradigmes multiples qui favorisent la programmation fonctionnelle, mais elles ne constituent pas une caractéristique unique des langages fonctionnels. Mais si vous les voyez comme une implémentation du λ-calcul, eh bien, ils font partie intégrante de la programmation fonctionnelle, l’essentiel étant que ce n’est pas si simple :)
yannis
La conception de Javascript empêche les implémentations d'être en mesure d'optimiser les appels différés. Dans mes livres, cela seul l'empêche d'être étiqueté comme fonctionnel.
dan_waterworth
I know it has objects & you can do OOP with it alsoNon, tu ne peux pas. C'est une programmation basée sur un prototype qui élimine la distinction entre classe et objet. Personnellement, j'estime que la programmation basée sur des prototypes présente des lacunes à ce niveau de base.
RokL
Javascript n'est pas un langage fonctionnel, il est certes doté de fonctionnalités fonctionnelles, mais il en va de même du vieil impératif C, en fait chaque langage possède les fonctionnalités fonctionnelles de base. Un langage purement fonctionnel, tel que Haskell, ML, etc., est un langage déclaratif et non impératif.
ALXGTV

Réponses:

72

Javascript est-il un langage fonctionnel? Je sais qu'il a des objets et que vous pouvez aussi faire de la programmation orientée objet, mais est-ce aussi un langage fonctionnel, peut-il être utilisé de cette manière?

Parfois, les gens vont parler de programmation fonctionnelle, alors qu’il s’agit de programmation impérative ou de programmation procédurale . À proprement parler, la programmation fonctionnelle est:

En informatique, la programmation fonctionnelle est un paradigme de la programmation qui considère le calcul comme une évaluation de fonctions mathématiques et évite les données d’état et mutables . Il met l'accent sur l'application de fonctions, contrairement au style de programmation impératif, qui met l'accent sur les changements d'état. La programmation fonctionnelle trouve ses racines dans le lambda calcul, un système formel mis au point dans les années 1930 pour étudier la définition, l'application et la récursivité des fonctions. De nombreux langages de programmation fonctionnels peuvent être considérés comme des élaborations du calcul lambda.

Bien que Javascript ne soit pas largement connu ou utilisé comme langage fonctionnel, il comporte certains éléments fonctionnels :

JavaScript a beaucoup en commun avec Scheme. C'est un langage dynamique. Il a un type de données flexible (tableaux) qui peut facilement simuler des expressions s. Et plus important encore, les fonctions sont lambdas.

Scheme est un dialecte de Lisp et est probablement l'un des langages auxquels la plupart des programmeurs pensent lorsqu'ils discutent de programmation fonctionnelle. En matière d' orientation d'objet , Javascript est un langage orienté objet. Mais son orientation objet est basée sur un prototype :

La programmation par prototype est un style de programmation orientée objet dans laquelle les classes ne sont pas présentes. La réutilisation des comportements (appelée héritage dans les langages basés sur les classes) est effectuée via un processus de clonage d'objets existants qui servent de prototypes. Ce modèle peut également être appelé programmation sans classe, orientée prototype ou instance. La délégation est la fonctionnalité de langage qui prend en charge la programmation basée sur un prototype.

Donc, bien que Javascript soit orienté objet, il ne suit pas le plus courant modèle basé sur les classes , pas plus que les langages tels que C ++, C #, Java et PHP (et quelques autres). Et bien sûr, c'est aussi un langage impératif, ce qui crée une confusion avec la programmation fonctionnelle que j'ai décrite ci-dessus.

Vous savez comment la programmation orientée objet est devenue / semble être la prochaine évolution de la programmation. Cela signifie-t-il que la "programmation fonctionnelle" constitue la prochaine évolution?

L’orientation objet et la programmation fonctionnelle ne sont que deux exemples parmi tant d'autres. paradigmes de programmation , ce sont des styles de programmation différents avec des concepts et des abstractions différents. Le mot clé est "différent". Il n’existe pas de paradigme unique qui soit meilleur que les autres ou plus évolué que d’autres, chacun correspond à certains scénarios mieux que les autres. Certains sont peut-être plus âgés que d'autres, mais en termes d'évolution, cela les rend meilleurs, car ils ont survécu plus longtemps. Mais ce n'est pas une façon très intelligente de voir les choses.

Javascript, comme je l'ai décrit ci-dessus et dans de nombreux autres langages, est multi-paradigme. Il vous permet d'écrire du code dans un style impératif, orienté objet et fonctionnel, basé sur un prototype. C'est à vous de choisir lequel convient le mieux à votre projet. Il existe également plusieurs langages de paradigme uniques, l'exemple canonique étant Java, qui permet uniquement la programmation orientée objet basée sur les classes. 1 .

Vous devriez vraiment résister à toute envie de traiter les langues et les paradigmes comme des déclarations de mode. Il y a une abudance de merde là-bas, la plupart du temps écrite par des fanboys / fangirls ou des gens du marketing, avec très peu de connaissances (voire aucune) et de compréhension de la programmation. Des termes tels que "meilleur", "plus évolué", etc., ne s'appliquent tout simplement pas.

J'apprends mieux par des exemples. Peut-être que quelqu'un pourrait montrer qu'il exécute la même tâche de manière POO, puis de manière programmée, pour comprendre et comparer ce que la programmation fonctionnelle fait / est.

Ce serait une façon terrible d'apprendre. L’orientation fonctionnelle et l’objet sont des styles assez différents, et tout exemple autre que terriblement simple ne s’adapterait pas à l’un ou l’autre style.

1 Mais récemment, tente d’étendre sa portée à la programmation générique, voyons comment cela se passe.


En conclusion:

  • Concentrez-vous sur l'apprentissage du Javascript, c'est un langage magnifique et extrêmement utile. Apprenez la langue, pas le battage médiatique.
  • Plusieurs paradigmes différents, tous également utiles. A vous de choisir lequel vous préférez et lequel convient le mieux à votre projet.
  • Si vous souhaitez apprendre la programmation fonctionnelle, choisissez un langage plus adapté, tel que Scheme ou Clojure . Mais vous devez d'abord comprendre les concepts mathématiques impliqués.
  • Faites des recherches avant de demander. La plupart de vos questions trouvent une réponse dans les articles correspondants de Wikipedia. Savoir faire des recherches et poser des questions est une compétence extrêmement importante pour tout programmeur.
Yannis
la source
5
+1 Grande réponse. En raison de la façon dont la formation à la programmation est structurée, les nouveaux développeurs semblent penser que les paradigmes sont exclusifs et discrets, mais ils ne le sont pas. Essayez d’écrire du code POO qui tire parti des concepts fonctionnels lorsque cela a du sens. La programmation événementielle est un paradigme, mais certains aspects de l’informatique influent certainement sur tous les programmes graphiques et Web. Le polymorphisme , une caractéristique essentielle de la programmation orientée objet, est une programmation vraiment générique. Nommer ces idées nous aide à conceptualiser une bonne programmation, mais vous ne devriez pas en utiliser une à l’exclusion des autres.
kojiro
Bien que la question initiale et votre réponse décrivent Javascript et sa relation avec la programmation fonctionnelle, je pense que votre réponse est l'une des meilleures comparaisons que j'ai vues entre la programmation OO et la programmation fonctionnelle. Bien joué.
AnotherDeveloper
«Ce serait une façon terrible d'apprendre.» Je viens de terminer la lecture de ce livre qui présente un problème et le résout avec un éventail de paradigmes, y compris les styles POO et FP: github.com/crista/exercises-in-programming-style . J'ai beaucoup appris de ça!
Nick
Cela ne peut @ Nick pour vous décrire ce que les regards de paradigme comme et comment cela fonctionne, mais il ne vous dit pas pourquoi , ce qui est sans doute l'aspect le plus important. Mais vous devez apprendre comment avant d’apprendre pourquoi :) parfois, nous oublions que ces choses sont un processus.
Matthew Brent
8

Javascript peut être utilisé comme langage fonctionnel, en fait il le fait très bien. Il est possible de mettre en œuvre que monads supporte une construction lambda, etc. Il ne s’agit pas exclusivement d’un langage fonctionnel, car il comporte également de nombreuses fonctionnalités orientées objet, mais il peut être utilisé de cette façon. En fait, j’aperçois que l’utilisation de Javascript comme langage fonctionnel est un excellent moyen de l’utiliser. (Exemple jQuery et underscore.js)

Zachary K
la source
bon et concis! Convenu que la programmation fonctionnelle est souvent le moyen le plus simple d’obtenir quelque chose en js.
Bunglestink
Encore plus intéressant que les monades, vous pouvez implémenter des flèches: JS ( cs.umd.edu/projects/PL/arrowlets ). Maintenant, à pourquoi quelqu'un voudrait veulent des flèches en JavaScript, c'est une question ouverte. Mais cela peut être fait.
Homme le
J'admettrai que je ne comprends pas assez sur les flèches pour savoir si elles seront utiles. Mais je travaille sur un livre sur les monades en Javascript et je pourrais ajouter un chapitre sur les flèches ( shop.oreilly.com/product/0636920023890.do )
Zachary K
6

L'évolution signifie normalement un changement progressif . La POO n'est pas un ajout incrémental à la programmation procédurale - en fait, elle est entièrement orthogonale à un modèle de programmation sous-jacent et peut être combinée à n'importe lequel d'entre eux. La programmation fonctionnelle n’est pas un ajout progressif à une procédure, une POO ou autre, mais une base alternative pour exprimer les principes informatiques fondamentaux, et c’est en fait le premier base de ce type jamais formulée, bien avant l'apparition des premiers ordinateurs. Il est important de comprendre que tous ces systèmes fondamentaux sont équivalents (l'un peut être exprimé en termes d'un autre).

Afin de comprendre l'approche fonctionnelle, vous devez d'abord acquérir les bases en mathématiques . Si vous souhaitez avoir une idée de ce que signifie coder dans un style fonctionnel en Javascript, commencez à utiliser jQuery .

SK-logic
la source
2

Non.

JavaScript est avant tout un langage orienté objet.

Cela ne veut pas dire que vous ne pouvez pas écrire de programmes JavaScript dans un style fonctionnel, car vous pouvez adopter un style fonctionnel dans n'importe quel langage complet de Turing si vous essayez suffisamment. Vous pouvez faire de la programmation fonctionnelle en assembleur si vous le souhaitez. Mais cela ne rend pas toutes les langues fonctionnelles. Vous pourriez aussi bien appeler Haskell imperative, ou Java un langage de programmation logique - si vous adoptiez cette approche, les termes deviendraient bientôt dépourvus de sens.

Pour classer une langue dans le paradigme approprié, l’OMI doit prendre en compte:

  • Quel est le style dominant permis par les constructions de langage (clairement la POO pour JavaScript, les langages fonctionnels insistent plutôt sur les fonctions et les valeurs de données immuables)
  • Quel paradigme est pris en charge dans les bibliothèques principales du langage (encore une fois clairement OOP pour JavaScript)
  • Quelles sont les fonctionnalités désactivées ou découragées dans la langue (les langages fonctionnels découragent ou interdisent les variables mutables, ce qui n'est pas le cas pour JavaScript)
  • Quel style de développement est répandu dans la communauté des développeurs utilisant le langage (là encore, la POO est clairement répandue dans le monde JavaScript)

Personnellement, je trouve assez amusant que beaucoup de gens aiment prétendre qu'une langue est "fonctionnelle" simplement parce que c'est un terme à la mode en ce moment :-)

Si vous souhaitez avoir une perspective un peu longue mais amusante des paradigmes de programmation au fil des ans, vous pouvez visionner la vidéo de Oncle Bob Martin "The Last Programming Language" . Pour moi, le grand intérêt de cet exposé est que les paradigmes de programmation sont définis par les fonctionnalités qu’ils emportent , et non par celles qu’ils ont insérées ......

Mikera
la source
What is the dominant style enabled by the language constructsJe vous mets au défi d’appliquer cela à Perl ... Ou à tout autre point, vraiment :)
yannis
2
Perl? Bon challenge! C'est un peu le langage d'assemblage dans le sens où vous pouvez pirater à peu près n'importe quel paradigme que vous voulez, mais dans l'usage courant que j'ai vu (script), il est principalement utilisé comme langage impératif / procédural.
mikera
Eh bien, oop est aussi assez commun. D'une manière perly bien sûr. Et fonctionnel aussi , bien que peu commun. perl, c'est juste du perl, ça n'a pas de sens d'essayer de donner un sens à ça :)
Yannis
JavaScript est légèrement plus fonctionnel que Java car il comporte au moins des fermetures et des fonctions de première classe. Mais votre droit, JavaScript est aussi fonctionnel que C #.
Raynos
2

Javascript est d'abord un prototype, avec des capacités fonctionnelles - accordées par son utilisation de fonctions en tant qu'objets de première classe.

Cela signifie que vous pouvez utiliser les fonctions en tant que données, ce qui a pour effet curieux de réduire le besoin de variables qui conservent l'état. Si vous constatez que vous cherchez une instruction var ou utilisez une ou plusieurs instructions "if", vous vous écartez d'un style fonctionnel.

Une autre particularité notable du style fonctionnel est que les fonctions doivent SEULEMENT renvoyer le résultat de leur évaluation et ne pas avoir d’effets secondaires sur l’état en dehors de leur champ d’application:

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

Les langages fonctionnels sont non destructifs, ce qui signifie qu'ils ne modifient pas l'entrée, mais renvoient plutôt des données entièrement nouvelles en fonction de l'entrée. Voir ce fil: https://stackoverflow.com/questions/749084/jquery-map-vs-each

Les langages fonctionnels présentent également de nombreuses méthodes communes, avec des noms tels que "map", "fold", "réduire" qui traitent les listes / collections. Dans JS, contrairement à d’autres langages, nous devons les créer manuellement - voir des bibliothèques comme underscore.js pour quelques exemples, bien que la dernière implémentation de JS en ait certaines directement dans la boîte.

La chose importante à garder à l’esprit (IMO) est que, même si JS peut utiliser certains modèles fonctionnels, il n’est pas toujours bien équipé pour l’exécuter.

Prenez une itération sur un tableau, par exemple. Vous pouvez le faire en utilisant un style fonctionnel ou les constructions de boucles natives - et d’une manière générale, la boucle est plus performante. Prenez cet exemple - frappez-le avec des boucles de taille croissante et enregistrez les temps d'exécution dans différents navigateurs (je l'ai déjà fait, mais j'ai perdu les repères - désolé!):

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;
    }
}

En outre, si vous utilisez une structure fonctionnelle pour générer des boucles de taille considérable sans utiliser une forme de gestion de pile ad-hoc, vous risquez d'inonder la pile (bien que, pour être juste, vous avez besoin d'une grande liste pour que cela se produise. ..). Vous devez également prendre en compte dans le mélange les optimisations de variantes de chaque navigateur - bien que, si vous travaillez dans un environnement Node.js, il s’agisse bien entendu d’une cible fixe.

Cela ne veut pas dire que vous ne devriez pas utiliser de constructions fonctionnelles en Javascript - soyez juste conscient des limitations de son implémentation par rapport à son environnement.

Voici quelques liens qui pourraient vous intéresser:

Un bon chapitre sur la programmation fonctionnelle en Javascript de l'excellent "Javascript éloquent"

Le petit schemer

un de mes amis a écrit une bibliothèque JS basée sur le Little Schemer

Un bon tutoriel sur les régimes qui pourrait vous aider à mieux comprendre la PF

Sunwukung
la source