Question

Après avoir regardé l'interview avec Rich Hickey sur Protocoles Clojure 1.2, et sachant très peu Clojure, j'ai quelques questions sur les protocoles Clojure:

  • Sont-ils l'intention de faire la même chose que Types de construction à Scala? Quels avantages les protocoles ont sur les types structurels (la performance, la flexibilité, la clarté du code, etc.)? Sont-ils mis en œuvre à travers des réflexions?
  • Questions sur l'interopérabilité avec Scala: Les protocoles peuvent être utilisés à la place des types structurels à Scala? Peuvent-ils être étendus (si « extension » terme peut être appliqué aux protocoles) à Scala?
Était-ce utile?

La solution

Totalement indépendant.

Scala est un langage typé statiquement. Clojure est un langage typé dynamiquement. Cette différence façonne les deux fondamentalement.

Des types structuraux statiques sont des types, période. Ils sont juste un moyen d'avoir le compilateur prouver statiquement qu'un objet aura une structure particulière (je dis prouver, mais la coulée peut provoquer des preuves fausses comme toujours).

Protocoles dans Clojure sont un moyen de créer l'envoi dynamique qui est beaucoup plus rapide que la réflexion ou à la recherche des choses dans une carte. Dans un sens sémantique qu'ils ne touchent pas vraiment les capacités de Clojure, mais sur le plan opérationnel elles sont nettement plus vite que les mécanismes utilisés avant.

traits Scala sont un peu plus près de protocoles, comme les interfaces Java, mais encore une fois il y a un problème statique vs dynamique. traits de Scala doivent être associés à une classe au moment de la compilation, similaire aux interfaces Java. protocoles de Clojure peuvent être ajoutés à un type de données lors de l'exécution après le fait même par un tiers.

Quelque chose comme des protocoles Clojure est possible en Java et Scala grâce à des mécanismes tels que wrapper / modèles proxy ou proxy dynamiques ( http://download.oracle.com/javase/1.4.2/docs/guide/reflection/proxy.html ). Mais ceux-ci seront un diable de beaucoup plus maladroits que les protocoles Clojure et droit d'obtenir l'identité d'objet est délicat aussi bien.

Autres conseils

Le but des protocoles dans Clojure est de résoudre le problème d'expression d'une manière efficace.

[Voir:. explication simple des protocoles de Clojure ]

La solution de Scala à l'expression sont les problèmes Implicits. Ainsi, sémantiquement, que est le plus proche équivalent à protocoles Clojure à Scala. (Dans Haskell, il serait peut-être de type ou classes de types familles.)

Comme je l'ai compris de cette introduction blogpost , les protocoles de fermeture sont plus proches de Scala caractères, plutôt que des types structurels (et donc, ne peut pas être utilisé comme un remplacement pour eux, répondre à ma deuxième question):

/* ----------------------- */
/* --- 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..."
}

D'autres réponses mieux parler aux autres parties de votre question, mais:

  

Sont-ils mis en œuvre par   réflexions?

Non - protocoles sont compilés à des interfaces JVM. Les choses qui mettent en œuvre des protocoles (réifier, defrecord, etc.) sont compilés à des classes JVM qui mettent en œuvre l'interface de protocole, afin que les appels à des fonctions de protocole sont les mêmes que les appels de méthode machine virtuelle Java standard sous le capot.

C'était en fait l'un des facteurs de motivation pour les protocoles - beaucoup de structures de données internes de Clojure ont été écrites en Java, pour des raisons de vitesse, parce qu'il n'y avait pas moyen de faire l'envoi polymorphique pleine vitesse dans Clojure pure. Les protocoles prévoient que. Clojure a encore beaucoup de Java dans son code source, mais cela pourrait tout peut maintenant être réécrite en Clojure sans perte de performance.

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