Risposte:
Ancora una volta, sembra che abbia risposto alla mia domanda diventando impaziente e facendolo in #clojure su Freenode. La cosa buona è rispondere alle tue domande su Stackoverflow.com: D
Ho avuto una breve discussione con Rich Hickey, ed ecco il senso.
[12:21] <Raynes> Vectors aren't seqs, right?
[12:21] <rhickey> Raynes: no, but they are sequential
[12:21] <rhickey> ,(sequential? [1 2 3])
[12:21] <clojurebot> true
[12:22] <Raynes> When would you want to use a list over a vector?
[12:22] <rhickey> when generating code, when generating back-to-front
[12:23] <rhickey> not too often in Clojure
Se hai programmato molto Java e hai familiarità con il framework di raccolta Java, pensa a liste come LinkedList
e vettori simili ArrayList
. Quindi puoi praticamente scegliere i contenitori allo stesso modo.
Per ulteriori chiarimenti: se si intende aggiungere elementi singolarmente all'inizio o alla fine della sequenza, un elenco collegato è molto meglio di un vettore, poiché gli elementi non devono essere mescolati ogni volta. Tuttavia, se si desidera accedere frequentemente a elementi specifici (non vicino alla parte anteriore o posteriore dell'elenco) (ad esempio, accesso casuale), è necessario utilizzare il vettore.
A proposito, i vettori possono essere facilmente trasformati in seq.
user=> (def v (vector 1 2 3))
#'user/v
user=> v
[1 2 3]
user=> (seq v)
(1 2 3)
user=> (rseq v)
(3 2 1)
ArrayList
senza, effettivamente, reimplementarti ArrayDeque
.
I vettori hanno tempi di accesso casuali O (1), ma devono essere preallocati. Gli elenchi possono essere estesi dinamicamente, ma l'accesso a un elemento casuale è O (n).
Quando usare un vettore:
Quando utilizzare un elenco:
~O(1)
, per coloro ai quali questa spiegazione dei costi potrebbe essere utile - stackoverflow.com/questions/200384/constant-amortized-time
solo una breve nota a margine:
"Ho letto che i vettori non sono seq, ma gli elenchi lo sono."
le sequenze sono più generiche di elenchi o vettori (o mappe o set).
È un peccato che REPL stampi gli elenchi e le sequenze allo stesso modo perché fa sembrare che gli elenchi siano sequenze anche se sono diversi. la funzione (seq) farà una sequenza da molte cose diverse tra cui gli elenchi, e puoi quindi alimentare quel seq a una qualsiasi delle tante funzioni che fanno cose belle con seqs.
user> (class (list 1 2 3))
clojure.lang.PersistentList
user> (class (seq (list 1 2 3)))
clojure.lang.PersistentList
user> (class (seq [1 2 3]))
clojure.lang.PersistentVector$ChunkedSeq
Sec ha un collegamento che restituisce il suo argomento se è già un seq:
user> (let [alist (list 1 2 3)] (identical? alist (seq alist)))
true
user> (identical? (list 1 2 3) (seq (list 1 2 3)))
false
static public ISeq seq(Object coll){
if(coll instanceof ASeq)
return (ASeq) coll;
else if(coll instanceof LazySeq)
return ((LazySeq) coll).seq();
else
return seqFrom(coll);
}
gli elenchi sono sequenze, anche se lo sono anche altre cose, e non tutte le sequenze sono elenchi.
class
invece class?
?
clojure.lang.PersistentList
per me. Sto assumendo si intende scrivere class
non class?
.
class
restituisce la stessa PersistentList per entrambe queste espressioni che hai menzionato, questo implica che sequenze ed elenchi sono davvero la stessa cosa?