2011-01-12 14 views
8

Il meta per il metilaggio viene conservato solo se una funzione si occupa di farlo e le funzioni fondamentali di Clojure non mantengono il meta in tutto il mondo. La regola generale che ho sentito è che le funzioni di raccolta come conj, assoc, ecc sono da preservare meta ma le funzioni di sequenza come map, filter, take, etc non preservano meta.Quali funzioni nel core Clojure preservano meta?

Esiste un elenco di quali funzioni DO conserva meta?

risposta

5

Si tratta di tipi. Le funzioni di sequenza agiscono come se chiamassero seq sul loro argomento e quindi non sempre restituiscono lo stesso tipo di oggetto. Le funzioni di raccolta e le funzioni specifiche del tipo non chiamano seq e restituiscono un oggetto dello stesso tipo di ciò che è stato loro assegnato. In un certo senso le fa dare l'illusione di restituire lo stesso oggetto (questo potrebbe essere il ragionamento per questo comportamento) anche se questo non è proprio il caso. Potremmo dire che la regola generale è che una funzione preserva la meta quando conserva il tipo.

user> (meta (seq (with-meta (list 1) {:a 1}))) 
{:a 1} 
user> (meta (seq (with-meta (vector 1) {:a 1}))) 
nil 

essere sicuri di essere a conoscenza di quando la pigrizia è coinvolto dura:

user> (type (list 1)) 
clojure.lang.PersistentList 
user> (type (map identity (list 1))) 
clojure.lang.LazySeq 
user> (meta (seq (with-meta (map identity (list 1)) {:a 1}))) 
nil 

Per un elenco delle funzioni che conserva meta sulla raccolta, vedere la pagina data structures. Quelli che non conservano meta si trovano nella pagina sequences, ad eccezione di quando restituiscono un oggetto dello stesso tipo.

Sotto il cofano io non sono molto sicuro circa i dettagli in quanto la pigrizia e Chunked sequenza è stato aggiunto, ma si può guardare ai cons, seq e seqFrom metodi dalla classe RT. Le funzioni che non preservano i meta-dati passano attraverso questi metodi. Mentre le funzioni di raccolta finiscono per utilizzare metodi specifici per i loro tipi.

Problemi correlati