Question

Je travaille avec Node.js pendant un certain temps sur une application de chat (je sais, très original, mais je pensais que ce serait un bon projet d'apprentissage). Underscore.js fournit beaucoup de concepts de programmation fonctionnels qui semblent intéressants, donc je voudrais comprendre comment un programme fonctionnel JavaScript serait la configuration.

De ma compréhension de la programmation fonctionnelle (qui peut se tromper), l'idée est d'éviter les effets secondaires, qui sont une fonction ayant peu ou prou qui met à jour une autre variable en dehors de la fonction donc quelque chose comme

var external;
function foo() {
   external = 'bar';
}
foo();

serait la création d'un effet secondaire, correct? Donc, en règle générale, vous voulez éviter les variables déranger dans la portée globale.

Ok, alors comment ça marche quand vous avez affaire à des objets et ce qui ne? Par exemple, beaucoup de fois, je vais avoir un constructeur et une méthode d'initialisation qui initialise l'objet, comme suit:

var Foo = function(initVars) {
   this.init(initVars);
}

Foo.prototype.init = function(initVars) {
   this.bar1 = initVars['bar1'];
   this.bar2 = initVars['bar2'];
   //....
}

var myFoo = new Foo({'bar1': '1', 'bar2': '2'});

Alors ma méthode init provoque intentionnellement des effets secondaires, mais ce serait une manière fonctionnelle pour gérer le même genre de situation?

En outre, si quelqu'un pouvait me pointer soit un code source Python ou JavaScript d'un programme qui essaie d'être aussi fonctionnel que possible, ce serait aussi très apprécié. Je sens que je suis près de « l'obtenir », mais je ne suis pas tout à fait. Principalement je suis intéressé par la façon dont fonctionne la programmation fonctionnelle avec le concept de classes de POO traditionnelle (ou supprime pour quelque chose de différent si tel est le cas).

Était-ce utile?

La solution

Vous devriez lire cette question:

Javascript comme langage fonctionnel

Il y a beaucoup de liens utiles, y compris:

Maintenant, mon avis. Beaucoup de gens JavaScript mal comprendre , peut-être parce que son apparence de syntaxe comme la plupart des autres langages de programmation (où Lisp / Haskell / OCaml look complètement différent). JavaScript est pas orienté objet, il est en fait un prototype basé langue . Il n'a pas les classes ou l'héritage classique ne devrait donc pas vraiment être comparé à Java ou C ++.

JavaScript peut être mieux comparé à un Lisp; il a des fermetures et des fonctions de première classe. En les utilisant, vous pouvez créer d'autres techniques de programmation fonctionnelle, comme application partielle ( corroyage).

Prenons un exemple (en utilisant sys.puts de Node.js):

var external;
function foo() {
    external = Math.random() * 1000;
}
foo();

sys.puts(external);

Pour se débarrasser des effets secondaires mondiaux, nous pouvons l'envelopper dans une fermeture:

(function() {
    var external;
    function foo() {
        external = Math.random() * 1000;
    }
    foo();

    sys.puts(external);
})();

Notez que nous ne pouvons pas faire quoi que ce soit avec external ou foo en dehors du champ d'application. Ils sont complètement enveloppés dans leur propre fermeture, intouchable.

Maintenant, pour se débarrasser de la external effet secondaire:

(function() {
    function foo() {
        return Math.random() * 1000;
    }

    sys.puts(foo());
})();

En fin de compte, l'exemple n'est pas purement fonctionnel car il ne peut pas soit. L'utilisation d'un nombre aléatoire lit à partir de l'état global (pour obtenir une graine) et l'impression à la console est un effet secondaire.

Je veux aussi souligner que le mélange de programmation fonctionnelle avec des objets est parfaitement bien. Prenez ceci par exemple:

var Square = function(x, y, w, h) {
   this.x = x;
   this.y = y;
   this.w = w;
   this.h = h;
};

function getArea(square) {
    return square.w * square.h;
}

function sum(values) {
    var total = 0;

    values.forEach(function(value) {
        total += value;
    });

    return total;
}

sys.puts(sum([new Square(0, 0, 10, 10), new Square(5, 2, 30, 50), new Square(100, 40, 20, 19)].map(function(square) {
    return getArea(square);
})));

Comme vous pouvez le voir, en utilisant des objets dans un langage fonctionnel peut être très bien. Certains ont même Lisps choses appelées listes de propriétés qui peuvent être considérés comme des objets.

Le vrai truc à utiliser des objets dans un style fonctionnel est de vous assurer que vous ne comptez pas sur leurs effets secondaires, mais au lieu de les traiter comme immuable. Un moyen facile est à chaque fois que vous souhaitez modifier une propriété, il suffit de créer un nouveau objet avec les nouveaux détails et passer qu'un long, au lieu (ce qui est l'approche souvent utilisée dans Clojure et Haskell).

Je crois fermement que les aspects fonctionnels peuvent être très utiles en JavaScript, mais en fin de compte, vous devez utiliser tout ce qui rend le code plus lisible et ce qui fonctionne pour vous.

Autres conseils

Vous devez comprendre que la programmation fonctionnelle et la programmation orientée objet sont un peu antithétique à l'autre. Il est impossible de tous les deux purement fonctionnelle et purement orienté objet.

de programmation fonctionnelle est tout au sujet des calculs sans état. la programmation orientée objet est tout au sujet des transitions d'état. (Paraphasing cette . Espérons pas trop mal)

JavaScript est plus orienté objet que fonctionnel. Ce qui signifie que si vous voulez programmer dans un style purement fonctionnel, vous devez renoncer à une grande partie de la langue. Plus précisément toutes les parties orient objet.

Si vous êtes prêt à être plus pragmatique à ce sujet, il y a quelques inspirations du monde purement fonctionnel que vous pouvez utiliser.

J'essaie de respecter les règles suivantes:

Fonctions qui effectuent des calculs ne doivent pas état alter. Et les fonctions que l'état alter ne doivent pas effectuer des calculs. En outre, les fonctions que l'état alter devraient modifier aussi peu que possible l'état. L'objectif est d'avoir beaucoup de petites fonctions qui ne font qu'une chose. Ensuite, si vous avez besoin de faire quoi que ce soit grand, vous rédigez un tas de petites fonctions pour faire ce que vous avez besoin.

Il y a un certain nombre d'avantages à tirer de suivre ces règles:

  1. Facilité de réutilisation. La fonction d'une plus longue et plus complexe, plus il est spécialisé aussi, et donc il est moins probable qu'il puisse être réutilisé. L'implication inverse est que les fonctions plus courtes ont tendance à plus générique et donc plus faciles à réutiliser.

  2. Fiabilité du code. Il est si elle est moins complexe plus facile de raisonner sur la justesse du code.

  3. Il est plus facile aux fonctions de test quand ils le font qu'une seule chose. De cette façon, il y a moins de cas particuliers à tester.

Mise à jour:

suggestion Incorporated de commentaire.

Mise à jour 2:

Ajout de quelques liens utiles.

Je pense que, http://documentcloud.github.com/underscore/ devrait être agréable convient pour ce que vous avez besoin - il fournit les fonctions les plus importantes d'ordre de plus pour la programmation fonctionnelle et ne possède pas des fonctions côté client pour la manipulation DOM que vous n'avez pas besoin pour le côté serveur. Bien que je n'ai pas d'expérience avec elle.

Comme une note latérale: caractéristique principale à mon humble avis de la programmation fonctionnelle est transparence référentielle d'une fonction - résultat de la fonction ne dépend que de ses paramètres - fonction ne dépend pas de changements sur d'autres objets et ne présente pas de changement, sauf sa valeur de résultat. Il est facile de raisonner sur l'exactitude du programme et très précieux pour la mise en œuvre de multi-threading prévisible (le cas échéant). Bien que JavaScript n'est pas la langue de pari pour FP - J'attends des structures de données immuables d'être très coûteux performance sage d'utiliser

.

2 choses à remarquer,

  1. Dans votre premier exemple votre variable ne serait pas une fuite dans la zone globale et la façon dont il doit être fait, essayez de ne jamais utiliser des variables sans les déclarer à-dire test = « données » provoqueraient des données à des fuites dans la zone globale.

  2. Votre deuxième exemple est correct aussi bien, et bar1 bar2 ne seraient déclarés sur l'objet Foo.

choses à garder à l'esprit essayer de ne pas abuser du prototypage car il applique à tous les objets que vous créez, cela pourrait être extrêmement gourmandes en mémoire en fonction de la façon dont vos objets sont complexes.

Si vous êtes à la recherche d'un cadre de développement d'applications, consultez la page ExtJs . Personnellement, je pense qu'il serait parfaitement dans le modèle que vous essayez de développer contre. Il suffit de garder à l'esprit la façon dont leur modèle de licence fonctionne avant d'être fortement investi.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top