Domanda

Dopo aver visto il colloquio con Rich Hickey su protocolli in Clojure 1.2, e sapendo molto poco di Clojure, ho alcune domande su Clojure protocolli:

  • Sono destinati a fare la stessa cosa di Tipi strutturali a Scala? Quali sono i vantaggi protocolli hanno più tipi strutturali (prestazioni, la flessibilità, la chiarezza del codice, ecc)? Sono realizzate attraverso riflessioni?
  • Domande in materia di interoperabilità con Scala: Can protocolli essere utilizzati al posto dei tipi strutturali a Scala? essi possono essere estesi (se il termine 'estensione' può essere applicato a protocolli) in Scala?
È stato utile?

Soluzione

totalmente estranei.

Scala è un linguaggio a tipizzazione statica. Clojure è un linguaggio tipizzato in modo dinamico. Questa differenza forme entrambi fondamentalmente.

tipi strutturali sono tipi statici, punto. Sono solo un modo per avere il compilatore dimostrare in modo statico che un oggetto avrà una particolare struttura (dico provare qui, ma di fusione può causare prove fasulle come sempre).

Protocolli in Clojure sono un modo per creare la spedizione dinamica che è molto più veloce di riflessione o in cerca cose in una mappa. In un certo senso semantico che in realtà non si estendono le capacità di Clojure, ma operativamente sono significativamente più veloce rispetto ai meccanismi utilizzati prima.

tratti

??Scala sono un po 'più vicino ai protocolli, così come lo sono interfacce Java, ma ancora una volta c'è una statica e dinamica problema. tratti Scala devono essere associati con una classe al momento della compilazione, simile a interfacce Java. protocolli Clojure possono essere aggiunti a un tipo di dati in fase di esecuzione dopo il fatto, anche da parte di terzi.

Qualcosa di simile protocolli Clojure è possibile in Java e Scala attraverso meccanismi come involucro / proxy pattern o proxy dinamici ( http://download.oracle.com/javase/1.4.2/docs/guide/reflection/proxy.html ). Ma quelli sarà un diavolo di un goffo sacco di protocolli Clojure e ottenere destra oggetto identità è difficile pure.

Altri suggerimenti

Lo scopo dei protocolli in Clojure è quello di risolvere il problema Expression in modo efficiente.

[vedi:. semplice spiegazione dei protocolli Clojure ]

La soluzione di Scala alla Expression problema sono impliciti. Così, semanticamente, che è l'equivalente più a Clojure protocolli a Scala. (In Haskell, sarebbe Typeclasses o forse tipo Famiglie.)

Come ho capito da questa introduttivo blogpost , chiusura protocolli sono più vicini alla Scala Tratti, piuttosto che Tipi strutturali (e quindi, non possono essere utilizzati in sostituzione di loro, rispondere alla mia seconda domanda):

/* ----------------------- */
/* --- Protocol definition */
/* ----------------------- */

(defprotocol Fly
  "A simple protocol for flying"
  (fly [this] "Method to fly"))

/* --- In Scala */    
trait Fly{
    def fly: String
}

/* --------------------------- */
/* --- Protocol implementation */
/* --------------------------- */

(defrecord Bird [nom species]
  Fly
  (fly [this] (str (:nom this) " flies..."))

/* --- In Scala */    
case class Bird(nom: String, species: String) extends Fly{
    def fly = "%s flies..." format(nom)
}

/* --------------------- */
/* --- Dynamic extension */
/* --------------------- */

(defprotocol Walk
  "A simple protocol to make birds walk"
  (walk [this] "Birds want to walk too!"))

(extend-type Bird
  Walk
  (walk [this] (str (:nom this) " walks too..."))

/* --- In Scala */    
trait Walk{
    def walk = "Birds want to walk too!"
}

implicit def WalkingBird(bird: Bird) = new Walk{
    override def walk = "%s walks too..." format(bird.nom)
}

/* --------------- */
/* --- Reification */
/* --------------- */

(def pig (reify
                Fly (fly [_] "Swine flu...")
                Walk (walk [_] "Pig-man walking...")))

/* --- In Scala */    
object pig extends Fly with Walk{
    def fly = "Swine flu..."
    override def walk = "Pig-man walking..."
}

Altre risposte parlano alle altre parti della vostra domanda migliore, ma:

Stanno attuato mediante riflessioni?

No - i protocolli vengono compilati alle interfacce JVM. Cose che implementano protocolli (reificare, defrecord, ecc) sono compilati a classi JVM che implementano l'interfaccia protocollo, così chiamate alle funzioni di protocollo sono le stesse chiamate di metodo JVM standard, sotto il cofano.

Questo è stato in realtà uno dei motivatori per i protocolli - un sacco di strutture di dati interni di Clojure sono stati scritti in Java, per ragioni di velocità, perché non c'era modo di fare piena velocità spedizione polimorfico in puro Clojure. I protocolli prevedono che. Clojure ha ancora un sacco di Java nel suo codice sorgente, ma che potrebbe tutto può ora essere riscritto in Clojure senza perdita di prestazioni.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top