“Le chiusure sono oggetti dell’uomo povero e viceversa” – Cosa significa?

Le chiusure sono oggetti dell’uomo povero e viceversa.

Ho visto questa affermazione in molti punti del web ( incluso SO ) ma non capisco cosa significhi. Qualcuno potrebbe spiegare cosa significa esattamente?

Se ansible, includi esempi nella risposta.

Il punto è che chiusure e oggetti realizzano lo stesso objective: incapsulamento di dati e / o funzionalità in un’unica unità logica.

Ad esempio, potresti creare una class Python che rappresenta un cane come questo:

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!" 

E poi istanzia la class come object

 >>> Shaggy = Dog() 

L’object Shaggy ha dati e funzionalità integrati. Quando chiamo Shaggy.feed(5) , guadagna una sterlina. Quella libbra è memorizzata nella variabile che è memorizzata come attributo dell’object, che più o meno significa che è nell’ambito interno dell’object.

Se stavo codificando qualche Javascript, farei qualcosa di simile:

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

Qui, invece di creare un ambito all’interno di un object, ho creato un ambito all’interno di una funzione e poi ho chiamato quella funzione. La funzione restituisce un object JavaScript composto da alcune funzioni. Poiché tali funzioni accedono ai dati allocati nell’ambito locale, la memoria non viene recuperata, consentendo di continuare a utilizzarli tramite l’interfaccia fornita dalla chiusura.

Gli oggetti sono le chiusure dell’uomo povero.

Considera Java. Java è un linguaggio di programmazione orientato agli oggetti senza supporto di livello linguistico per le chiusure lessicali reali. Come un programmatore Java che lavora, le classi interne anonime possono chiudere le variabili disponibili in ambito lessicale (a condizione che siano final ). In questo senso, gli oggetti sono le chiusure dell’uomo povero.

Le chiusure sono oggetti di un povero uomo.

Considera Haskell. Haskell è un linguaggio funzionale senza supporto di livello linguistico per oggetti reali. Tuttavia possono essere modellati usando chiusure, come descritto in questo eccellente articolo di Oleg Kiselyov e Ralf Lammel. In questo senso, le chiusure sono oggetti poveri dell’uomo.


Se vieni da un ambiente OO, probabilmente troverai il pensiero in termini di oggetti più naturali e potresti quindi considerarli un concetto più fondamentale delle chiusure. Se provieni da uno sfondo FP, potresti trovare il modo di pensare in termini di chiusure più naturali, e potresti quindi considerarle un concetto più fondamentale degli oggetti.

La morale della storia è che chiusure e oggetti sono idee che sono espresse in termini l’una dell’altra, e nessuna è più fondamentale dell’altra . Questo è tutto ciò che c’è da dire sulla dichiarazione.

In filosofia, questo è indicato come realismo dipendente dal modello .

Un object, nel modo più semplice, è solo un insieme di stati e funzioni che operano su quello stato. Una chiusura è anche una raccolta di stati e una funzione che opera su quello stato.

Diciamo che chiamo una funzione che richiede una richiamata. In questo callback, ho bisogno di operare su uno stato noto prima della chiamata alla funzione. Posso creare un object che incorpori questo stato (“campi”) e contenga una funzione membro (“metodo”) che funge da callback. Oppure, potrei prendere il percorso facile e veloce (“povero uomo”) e creare una chiusura.

Come object:

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

Questo è pseudo-C #, ma è simile nel concetto ad altri linguaggi OO. Come puoi vedere, c’è una buona dose di codice in gioco con la class di callback per gestire lo stato. Questo sarebbe molto più semplice usando una chiusura:

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

Questo è un lambda (ancora, nella syntax C #, ma il concetto è simile in altri linguaggi che supportano le chiusure) che ci fornisce tutte le funzionalità della class, senza dover scrivere, utilizzare e mantenere una class separata.

Sentirai anche il corollario: “gli oggetti sono la chiusura di un povero uomo”. Se non posso o non voglio approfittare delle chiusure, allora sono costretto a fare il loro lavoro usando gli oggetti, come nel mio primo esempio. Sebbene gli oggetti offrano più funzionalità, le chiusure sono spesso una scelta migliore dove una chiusura funzionerà, per i motivi già indicati.

Quindi, un uomo povero senza oggetti può spesso ottenere il lavoro con chiusure, e un uomo povero senza chiusure può ottenere il lavoro usando gli oggetti. Un uomo ricco ha entrambi e usa quello giusto per ogni lavoro.

MODIFICATO: il titolo della domanda non include “viceversa”, quindi cercherò di non assumere l’intento del richiedente.

I due campi comuni sono le lingue funzionali e quelle imperative. Entrambi sono strumenti che possono svolgere compiti simili in modi diversi con diversi gruppi di preoccupazioni.

Le chiusure sono oggetti di un povero uomo.

Gli oggetti sono le chiusure dell’uomo povero.

Individualmente, ogni affermazione di solito significa che l’autore ha qualche pregiudizio, in un modo o nell’altro, solitamente radicato nel loro conforto con una lingua o una class di linguaggio rispetto a un disagio con un’altra. Se non sono pregiudizi, possono essere vincolati con un ambiente o l’altro. Gli autori che ho letto dicono che questo genere di cose sono solitamente i tipi religiosi zeloti, puristi o linguistici. Evito i tipi religiosi della lingua, se ansible.

Le chiusure sono oggetti di un povero uomo. Gli oggetti sono le chiusure dell’uomo povero.

L’autore di questo è un “pragmatico” e anche abbastanza intelligente. Significa che l’autore apprezza entrambi i punti di vista e apprezza che siano concettualmente un’unica e identica. Questo è il mio tipo di compagno.

“Gli oggetti sono le chiusure di un povero uomo” non è solo una dichiarazione di qualche equivalenza teorica – è un idioma di Java comune. È molto comune utilizzare le classi anonime per concludere una funzione che acquisisce lo stato corrente. Ecco come viene utilizzato:

 public void foo() { final String message = "Hey ma, I'm closed over!"; SwingUtilities.invokeLater(new Runnable() { public void run() { System.out.println(message); } }); } 

Questo sembra molto simile al codice equivalente usando una chiusura in un’altra lingua. Ad esempio, utilizzando i blocchi Objective-C (poiché Objective-C è ragionevolmente simile a Java):

 void foo() { NSString *message = @"Hey ma, I'm closed over!"; [[NSOperationQueue currentQueue] addOperationWithBlock:^{ printf("%s\n", [message UTF8String]); }]; } 

L’unica vera differenza è che la funzionalità è racchiusa nella new Runnable() istanza di class anonima new Runnable() nella versione Java.

Solo tanto zucchero, perché le chiusure nascondono oggetti anonimi sotto le loro gonne.