75 votes

"Les fermetures sont les objets du pauvre et vice versa" - Qu'est-ce que cela signifie ?

Les fermetures sont les objets de l'homme pauvre et vice versa.

J'ai vu cette déclaration à l'adresse beaucoup de places sur le web ( y compris le SO ) mais je ne comprends pas bien ce que cela signifie. Quelqu'un pourrait-il m'expliquer ce que cela signifie exactement ?

Si possible, veuillez inclure des exemples dans votre réponse.

76voto

missingfaktor Points 44003

Les objets sont les fermetures de l'homme pauvre.

Considérez Java. Java est un langage de programmation orienté objet qui ne prend pas en charge, au niveau du langage, les fermetures lexicales réelles. Comme solution de rechange, les programmeurs Java utilisent des classes internes anonymes qui peuvent fermer les variables disponibles dans la portée lexicale (à condition qu'elles soient final ). En ce sens, les objets sont des fermetures de l'homme pauvre.

Les fermetures sont les objets de l'homme pauvre.

Considérons Haskell. Haskell est un langage fonctionnel qui ne prend pas en charge les objets réels au niveau du langage. Cependant, ils peuvent être modélisés à l'aide de closures, comme décrit dans le document este Excellent article d'Oleg Kiselyov et Ralf Lammel. En ce sens, les fermetures sont des objets de l'homme pauvre.


Si vous venez d'un milieu OO, il vous sera probablement plus naturel de penser en termes d'objets, et vous pourrez donc les considérer comme un concept plus fondamental que les fermetures. Si vous venez d'un milieu FP, vous trouverez peut-être plus naturel de penser en termes de fermetures, et pourrez donc les considérer comme un concept plus fondamental que les objets.

La morale de l'histoire est que les fermetures et les objets sont des idées qui peuvent être exprimées l'une par rapport à l'autre, et aucune n'est plus fondamentale que l'autre. . C'est tout ce qu'il y a à dire sur la déclaration en question.

En philosophie, on parle de réalisme dépendant du modèle .

8 votes

Il y a une petite différence dans la mesure où, dans les objets, l'état est explicitement défini lors de l'instanciation de l'objet. Dans les closures, l'état provient d'une portée externe inconnue. Ainsi, l'utilisation d'objets donne un code plus découplé, plus explicite et plus testable.

5 votes

Certains langages exigent la capture des variables dans une fermeture, ce qui signifie que la portée est explicitement définie.

5 votes

@dtheodor Je ne suis pas d'accord avec votre déclaration : L'état d'une fermeture est toujours prévisible en lisant du haut vers le bas de la fermeture. L'état d'un objet (du moins le style orienté objet), cependant, se trouve être ce qu'il se trouve être actuellement, puisque l'état et le code sont entremêlés. Les fermetures sont transparent référentiel alors que les objets ne le sont pas.

61voto

BenTrofatter Points 1453

Le fait est que les fermetures et les objets atteignent le même objectif : l'encapsulation de données et/ou de fonctionnalités dans une unité logique unique.

Par exemple, vous pouvez créer une classe Python qui représente un chien comme ceci :

class Dog(object):
    def __init__(self):
        self.breed = "Beagle"
        self.height = 12
        self.weight = 15
        self.age = 1
    def feed(self, amount):
        self.weight += amount / 5.0
    def grow(self):
        self.weight += 2
        self.height += .25
    def bark(self):
        print "Bark!"

Et ensuite j'instancie la classe en tant qu'objet

>>> Shaggy = Dog()

L'objet Shaggy intègre des données et des fonctionnalités. Lorsque j'appelle Shaggy.feed(5) il gagne un kilo. Cette livre est stockée dans une variable qui est stockée comme un attribut de l'objet, ce qui signifie plus ou moins qu'elle est dans la portée interne de l'objet.

Si je codais du Javascript, je ferais quelque chose de similaire :

var Shaggy = function() {
    var breed = "Beagle";
    var height = 12;
    var weight = 15;
    var age = 1;
    return {
        feed : function(){
            weight += amount / 5.0;
        },
        grow : function(){
            weight += 2;
            height += .25;
        },
        bark : function(){
            window.alert("Bark!");
        },
        stats : function(){
            window.alert(breed "," height "," weight "," age);
        }
    }
}();

Ici, au lieu de créer une portée dans un objet, j'ai créé une portée dans une fonction, puis j'ai appelé cette fonction. La fonction renvoie un objet JavaScript composé de quelques fonctions. Comme ces fonctions accèdent aux données qui ont été allouées dans la portée locale, la mémoire n'est pas récupérée, ce qui vous permet de continuer à les utiliser via l'interface fournie par la fermeture.

1 votes

Pour clarifier : Python permet également de créer des closures, mais JavaScript (2014) n'a pas de support pour les classes.

6 votes

Pour clarifier : JavaScript supporte également la POO, mais sans le mot clé "class".

0 votes

Depuis ES6 et plus (js moderne), vous pouvez utiliser le mot clé "class" pour écrire la POO d'une manière plus familière.

15voto

P Daddy Points 14228

Un objet, dans sa forme la plus simple, est juste une collection d'états et de fonctions qui opèrent sur ces états. Une fermeture est également une collection d'états et une fonction qui opère sur ces états.

Disons que j'appelle une fonction qui prend un callback. Dans ce callback, j'ai besoin d'opérer sur un état connu avant l'appel de la fonction. Je peux créer un objet qui incarne cet état ("fields") et contient une fonction membre ("method") qui fait office de callback. Ou bien, je peux prendre la voie rapide et facile (celle du pauvre) et créer une fermeture.

En tant qu'objet :

class CallbackState{
    object state;

    public CallbackState(object state){this.state = state;}

    public void Callback(){
        // do something with state
    }
}

void Foo(){
    object state = GenerateState();
    CallbackState callback = new CallbackState(state);
    PerformOperation(callback.Callback);
}

Il s'agit d'un pseudo-C#, mais son concept est similaire à celui d'autres langages OO. Comme vous pouvez le voir, il y a une bonne quantité de texte passe-partout impliqué dans la classe de rappel pour gérer l'état. Ce serait beaucoup plus simple en utilisant une fermeture :

void Foo(){
    object state = GenerateState();
    PerformOperation(()=>{/*do something with state*/});
}

Il s'agit d'un lambda (encore une fois, dans la syntaxe C#, mais le concept est similaire dans d'autres langages qui supportent les fermetures) qui nous donne toutes les capacités de la classe, sans avoir à écrire, utiliser et maintenir une classe séparée.

Vous entendrez aussi le corollaire : "les objets sont la fermeture du pauvre". Si je ne peux pas ou ne veux pas tirer parti des fermetures, je suis obligé de faire leur travail en utilisant des objets, comme dans mon premier exemple. Bien que les objets offrent plus de fonctionnalités, les fermetures sont souvent un meilleur choix lorsqu'une fermeture fonctionne, pour les raisons déjà mentionnées.

Par conséquent, un homme pauvre sans objets peut souvent faire le travail avec des fermetures, et un homme pauvre sans fermetures peut faire le travail en utilisant des objets. Un homme riche possède les deux et utilise la bonne solution pour chaque tâche.

7voto

codenheim Points 6836

ÉDITION : Le titre de la question n'inclut pas "vice versa", je vais donc essayer de ne pas présumer de l'intention de l'auteur de la question.

Les deux camps communs sont les langages fonctionnels et impératifs. Les deux sont des outils qui peuvent accomplir des tâches similaires de différentes manières avec des préoccupations différentes.

Les fermetures sont les objets de l'homme pauvre.

Les objets sont les fermetures de l'homme pauvre.

Individuellement, chaque déclaration signifie généralement que l'auteur a un certain parti pris, d'une manière ou d'une autre, généralement enraciné dans son confort avec une langue ou une classe de langue par rapport à son inconfort avec une autre. S'il ne s'agit pas d'un parti pris, il se peut qu'ils soient limités par un environnement ou l'autre. Les auteurs que je lis et qui disent ce genre de choses sont généralement des zélotes, des puristes ou des religieux de la langue. J'évite si possible les religieux de la langue.

Les fermetures sont les objets de l'homme pauvre. Les objets sont les fermetures de l'homme pauvre.

L'auteur de ce texte est un "pragmatique" et il est aussi très intelligent. Cela signifie que l'auteur apprécie les deux points de vue et sait qu'ils sont conceptuellement identiques. C'est mon genre d'homme.

1 votes

Je pense que vous avez oublié la partie "et vice versa" de la déclaration.

0 votes

Non, je ne l'ai pas manqué, je l'ai juste mal lu. Je ne savais pas si l'auteur de la question voulait dire que ça faisait partie de la citation, ou s'il voulait dire qu'il avait vu les deux versions de la citation. Maintenant que vous le soulignez, je vois ce que vous voulez dire, l'auteur de la déclaration est probablement impartial, appréciant les deux côtés, mais probablement médiateur d'une discussion entre certains "types religieux de langue zélés, puristes".

0 votes

Le titre de la question est "Closures are a poor man's objects" sans le "vice versa", donc je ne suis pas sûr de la réponse de l'auteur de la question. J'ai évidemment répondu au titre, mais peut-être pas au corps de la question. Mais bon.

5voto

DaGreek Points 59

Juste un peu de sucre, car les fermetures cachent des objets anonymes sous leurs jupes.

2 votes

+1 - Au niveau de la VM / du compilateur, tout est vraiment un "objet" d'une certaine sorte. Tout est dans un nom. Ceux d'entre nous qui ont implémenté des compilateurs savent que les préoccupations sont similaires. Tout ce qui doit être ramassé à la poubelle est un objet au fond.

3 votes

C'est une réponse factice, en fait. Peu importe que ce soit la même chose pour le compilateur ou l'interpréteur. Ce qui compte, c'est leur valeur en tant qu'abstractions. Sinon, je pourrais dire que tout n'est que 0 et 1, ce qui n'est pas vraiment utile.

1 votes

@YuriAlbuquerque Si l'on se réfère au modèle de la machine de Turing, il n'y a pas de 0 ; tout est un 1.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X