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 LinkedListe 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)
ArrayListsenza, 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.
classinvece class??
clojure.lang.PersistentListper me. Sto assumendo si intende scrivere classnon class?.
classrestituisce la stessa PersistentList per entrambe queste espressioni che hai menzionato, questo implica che sequenze ed elenchi sono davvero la stessa cosa?