2014-08-29 29 views
6

So che gli strumenti clojure.lang.IPersistentVector del clojure assoc, come in (assoc [0 1 2 3] 0 -1) ; => [-1 1 2 3]. Ho anche sentito (come nella risposta this) che il vettore di clojure non implementa dissoc, come in (dissoc [0 1 2 3] 0) ; => [1 2 3]. Se questa funzionalità è così facilmente riproducibile utilizzando subvec, esiste un motivo reale per cui non dovrebbe essere implementato in clojure.lang, clojure.core o anche contrib? Se no, c'è qualche ragionamento dietro a questo?Perché non è stato implementato per i vettori in clojure?

risposta

8

Dissoc non ha molto senso per i vettori per due motivi:

  1. Il significato di dissoc è "rimuovere un tasto". Non è possibile rimuovere una chiave da un vettore senza causare altri effetti collaterali (ad esempio spostando tutti i valori futuri)
  2. dissoc si comporterebbe relativamente male sui vettori se dovesse spostare tutte le chiavi successive - grosso modo O (n) con un bel po ' di GC. Il nucleo di Clojure generalmente evita l'implementazione di operazioni che non sono efficienti/non hanno senso per una particolare struttura di dati.

Fondamentalmente, se ci si trova a voler fare dissoc su un vettore, si sta probabilmente utilizzando la struttura dati errata. Una hashmap o set persistente è probabilmente una scelta migliore.

Se si desidera una struttura di dati che funziona come un vettore, ma supporta taglio e l'inserimento di elementi o sottosuccessioni in modo efficiente, allora vale la pena di verificare RRB alberi: https://github.com/clojure/core.rrb-vector

Problemi correlati