2011-01-12 10 views
8

Clojure meta solo se conserva si una función se encarga de hacerlo y las funciones centrales de Clojure no conservan los metadatos a nivel mundial. La regla general que he escuchado es que las funciones de recopilación como conj, assoc, etc. se supone que conservan las funciones meta, pero las funciones de secuencia como map, filter, take, etc. no conservan meta.¿Qué funciones en Clojure core preserve meta?

¿Hay alguna lista en alguna parte de qué funciones DO preserve meta?

Respuesta

5

Todo se basa en los tipos. Las funciones de secuencia actúan como si llamaran al seq en su argumento y, por lo tanto, no siempre devuelven el mismo tipo de objeto. Las funciones de recopilación y las funciones específicas de tipo no llaman a seq y devuelven un objeto del mismo tipo que el que se les asignó. En cierto modo, les da la ilusión de devolver el mismo objeto (este podría ser el razonamiento de este comportamiento) incluso si ese no es el caso. Podríamos decir que la regla de oro es que una función preserva el meta cuando preserva el tipo.

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

Asegúrese de estar al tanto de cuando la pereza está implicada 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 

Para obtener una lista de funciones que conserva meta en la recopilación, ver la página data structures. Los que no conservan meta están en la página sequences, con la excepción de cuando devuelven un objeto del mismo tipo.

Bajo el capó no estoy muy seguro acerca de los detalles desde la pereza y la secuencia fragmentada se ha agregado, pero se puede ver en las cons, seqseqFrom y métodos de la clase RT. Las funciones que no conservan los metadatos pasan por estos métodos. Mientras que las funciones de recolección terminan usando métodos específicos para sus tipos.

Cuestiones relacionadas