Non ho capito l'utilizzo della funzione reify in Clojure. A cosa serve il clojure?Che cosa è reify in Clojure?
Potrebbe fornire degli esempi?
Non ho capito l'utilizzo della funzione reify in Clojure. A cosa serve il clojure?Che cosa è reify in Clojure?
Potrebbe fornire degli esempi?
reify
macro consente di creare una classe anonima che estende la classe java.lang.Object
e/o l'implementazione di interfacce/protocolli specificati. Gli API docs non descrivono chiaramente lo scopo, ma forniscono piuttosto i dettagli tecnici su cosa fa quella macro. Java interop documentation fornisce una breve descrizione dello scopo:
Al Clojure 1.2, reify è disponibile per l'attuazione interfacce anche.
Ancora più informazioni possono essere trovate in datatypes documentatio n dove è possibile trovare una descrizione molto dettagliata ciò che fa e come si confronta con proxy
:
Mentre DEFTYPE e defrecord definire i tipi di nome, reificare definisce sia un tipo anonimo e crea un'istanza di quel tipo. Il caso d'uso è in cui è necessaria un'implementazione una tantum di uno o più protocolli o interfacce e si desidera sfruttare il contesto locale. In questo rispetto è un caso d'uso simile al proxy, o classi interne anonime in Java.
I corpi di metodo di reify sono chiusure lessicali e possono fare riferimento allo scope locale circostante . reify differisce dal proxy in quanto:
Sono supportati solo protocolli o interfacce, nessuna superclasse in calcestruzzo. I corpi metodo sono veri metodi della classe risultante, non fns esterni. L'invocazione dei metodi sull'istanza è diretta, non , utilizzando la ricerca mappa. Nessun supporto per lo scambio dinamico dei metodi nella mappa del metodo . Il risultato è una prestazione migliore rispetto al proxy, sia nella costruzione e nel richiamo di . reify è preferibile al proxy in tutti i casi dove i suoi vincoli non sono proibitivi.
Non è possibile estendere una classe (diversa da 'Object') con' reify', quindi la prima frase è leggermente errata –
@NathanDavis Sì, hai ragione, ho risolto la mia risposta. –
reify
è quello di defrecord
cosa fn
è quello di defn
.
"Ah giusto ...... quindi qual è reify
"
In parole povere, i protocolli sono gli elenchi delle funzioni un tipo di dati dovrebbe sostenere, i record sono i tipi di dati e reificazioni sono tipi di dati anonimi.
Forse questo è prolisso, ma reify
non può essere compresa senza capire concretamente protocolli e tipi/record: Protocolli sono un modo per utilizzare lo stesso nome per una funzione come conj
che effettivamente agisce in modo diverso quando somministrato argomenti diversi ((conj [:b :c] :a) => [:b :c :a]
ma (conj '(:b :c) :a) => (:a :b :c)
). I record sono come oggetti o tipi (ma si comportano come mappe che li rendono più favolosi).
Più fondamentalmente, l'obiettivo è quello di risolvere "il problema Expression" che è quello di avere la capacità di senza aggiungere nuovi tipi di dati che lavorano con le funzioni esistenti, e nuove funzioni che si integrano perfettamente con i dati esistenti.
Così un giorno dici a te stesso: "Sè, dovresti imparare cosa vuol dire essere un'anatra!" così si scrive un protocollo:
(defprotocol Quacks
(quack [_] "should say something in ducky fashion"))
ma è tutto troppo astratto in modo da 'reale ify' esso:
(def donald (reify Quacks
(quack [_] "Quacks and says I'm Donald")))
Ora finalmente si può sperimentare la tua creazione:
(quack donald) => "Quacks and says I'm Donald"
Poi ti ricordi di Daffy:
(def daffy (reify Quacks
(quack [_] (str "Quacks and says I'm Daffy"))))
(quack daffy) => "Quacks and says I'm Daffy"
Ma per il momento si ricordi di Huey, a realizzare il vostro errore e definire ciò che un anatra è in un certo senso riutilizzabile:
(defrecord Duck [name]
Quacks
(quack [_] (str "Quacks and says I'm " name)))
e fare new
anatre (ci sono diversi modi per farlo):
(def huey (->Duck "Huey"))
(def duey (Duck. "Duey"))
(def louie (new Duck "Louie"))
(quack huey) => "Quacks and says I'm Huey"
ricordate che i record si comportano come le mappe (grazie a protocolli!):
(:name huey) => "Huey"
Ma poi ti ricordi che anatre sono non sono le uniche cose che ciarlatano, in modo da scrivere un altro protocollo:
(defprotocol Walks
(walk [_] "should walk like a duck"))
ed estendere la definizione di anatra
(extend-type Duck
Walks
(walk [_] "waddle waddle"))
(walk louie) => "waddle waddle"
Ora possiamo estendere ad altri tipi di implementare lo stesso protocollo (insegnano la stessa funzione di come lavorare con le altre cose):
Quindi diciamo che vogliamo programmatori di ciarlatano troppo :-)
(defrecord Programmer [] Quacks
(quack [_] "Monads are simply monoids in a category of endofunctors..."))
(quack (Programmer.)) => "Monads are simply monoids in a category of endofunctors..."
Raccomando questo ottimo explanation of protocols, uno explanation of reify e uno chapter on protocols in "Clojure for the Brave and True".
Declinazione di responsabilità: questo è inteso solo per dare una prima comprensione di quali protocolli sono, non migliori pratiche su come usarli. "Psst! Ho risposto a questa domanda in gran parte per insegnare a me stesso, perché fino a ieri non avevo mai scritto il mio protocollo/interfaccia!" !.
Così, mentre spero che migliora l'apprendimento qualcun altro, io vivamente benvenuto critiche o suggerimenti edit-"
ci sono esempi a pagina doc: https://clojuredocs.org/clojure.core/reify – OlegTheCat