Ich weiß, dass dies conseine Sequenz und conjeine Sammlung zurückgibt. Ich weiß auch, dass conjder Artikel dem optimalen Ende der Sammlung cons"hinzugefügt" wird und der Artikel immer der Vorderseite "hinzugefügt" wird. Dieses Beispiel veranschaulicht diese beiden Punkte:
Gibt es Beispiele für Listen, bei denen conjvs. consunterschiedliche Verhaltensweisen aufweisen, oder sind sie wirklich austauschbar? Gibt es ein anderes Beispiel, in dem eine Liste und eine Sequenz nicht gleichwertig verwendet werden können?
Ein Unterschied besteht darin, dass conjeine beliebige Anzahl von Argumenten zum Einfügen in eine Sammlung akzeptiert wird, während consnur eines benötigt wird:
Beachten Sie, dass diese nicht wirklich austauschbar sind. Insbesondere clojure.lang.Consnicht implementiert clojure.lang.Counted, so dass ein Ein countes nicht länger eine konstante Zeitoperation ist (in diesem Fall würde es wahrscheinlich auf 1 + 3 reduzieren - die 1 kommt von der linearen Durchquerung über das erste Element, die 3 kommt von (next (cons 4 '(1 2 3))einem PersistentListund also Counted).
Die Absicht hinter den Namen ist, glaube ich, das consheißt, eine Sequenz 1 zu konsultieren (zu konstruieren) , wohingegen conjbedeutet, einen Gegenstand auf eine Sammlung zu setzen. Die seqdurch konstruiert consbeginnt mit dem Element als erstes Argument übergeben und hat als ihre next/ restTeil resultierenden das Ding von der Anwendung seqzu dem zweiten Argument; Wie oben gezeigt, ist das Ganze von Klasse clojure.lang.Cons. Gibt dagegen conjimmer eine Sammlung vom ungefähr gleichen Typ zurück wie die an sie übergebene Sammlung. (Ungefähr, weil aus a ein PersistentArrayMapwird, PersistentHashMapsobald es über 9 Einträge hinaus wächst.)
1 Traditionell gibt es in der Lisp-Welt consNachteile (ein Paar), so dass Clojure von der Lisp-Tradition abweicht, indem seine consFunktion eine Sequenz konstruiert, die keine Tradition hat cdr. Die verallgemeinerte Verwendung von cons"Konstruieren eines Datensatzes irgendeiner Art, um eine Reihe von Werten zusammenzuhalten" ist derzeit beim Studium der Programmiersprachen und ihrer Implementierung allgegenwärtig. Das ist es, was gemeint ist, wenn "Vermeiden von Konsing" erwähnt wird.
Was für eine fantastische Zusammenfassung! Mir war nicht bewusst, dass es einen Cons-Typ gab. Gut gemacht!
Daniel Yankowsky
Vielen Dank. Freut mich das zu hören. :-)
Michał Marczyk
2
Gibt übrigens als Sonderfall (cons foo nil)einen Singleton zurück PersistentList(und ebenfalls für conj).
Michał Marczyk
1
Eine weitere hervorragende Erklärung. Du bist wirklich ein Clojure Jedi!
Dbyrne
1
Nach meiner Erfahrung ist es wichtig, Listen als Listen und nicht als Sequenzen zu behandeln, wenn es auf die Leistung ankommt.
Cgrand
11
Mein Verständnis ist, dass das, was Sie sagen, wahr ist: Konj auf einer Liste entspricht den Nachteilen auf einer Liste.
Sie können sich Conj als Operation "Irgendwo einfügen" und Nachteile als Operation "Am Kopf einfügen" vorstellen. In einer Liste ist es am logischsten, am Kopf einzufügen, daher sind Konj und Contra in diesem Fall gleichwertig.
Ein weiterer Unterschied besteht darin, dass conjeine Sequenz als erstes Argument verwendet wird, alterwenn sie auf eine refSequenz aktualisiert wird:
(dosync(alter a-sequence-ref conj an-item))
Dies geschieht grundsätzlich (conj a-sequence-ref an-item)threadsicher. Das würde nicht funktionieren cons. Weitere Informationen finden Sie im Kapitel über Parallelität in der Programmierung von Clojure von Stu Halloway.
(cons foo nil)
einen Singleton zurückPersistentList
(und ebenfalls fürconj
).Mein Verständnis ist, dass das, was Sie sagen, wahr ist: Konj auf einer Liste entspricht den Nachteilen auf einer Liste.
Sie können sich Conj als Operation "Irgendwo einfügen" und Nachteile als Operation "Am Kopf einfügen" vorstellen. In einer Liste ist es am logischsten, am Kopf einzufügen, daher sind Konj und Contra in diesem Fall gleichwertig.
quelle
Ein weiterer Unterschied besteht darin, dass
conj
eine Sequenz als erstes Argument verwendet wird,alter
wenn sie auf eineref
Sequenz aktualisiert wird:Dies geschieht grundsätzlich
(conj a-sequence-ref an-item)
threadsicher. Das würde nicht funktionierencons
. Weitere Informationen finden Sie im Kapitel über Parallelität in der Programmierung von Clojure von Stu Halloway.quelle
Ein weiterer Unterschied ist das Verhalten der Liste?
quelle
In der Tupelo-Bibliothek gibt es spezielle Funktionen zum Hinzufügen oder Anhängen von Werten zu einer sequentiellen Sammlung:
quelle