Is there a reason why vectors can be used as keys in metadata when defined via ^
reader macro?
these all work:
(meta (with-meta {} {:int true}))
; => {:int true}
(meta ^{:int true} {})
; => {:int true}
(meta ^:int {})
; => {:int true}
here, the last doesn’t:
(meta (with-meta {} {[:tuple :int] true}))
; => {[:tuple :int] true}
(meta ^{[:tuple :int] true} {})
; => {[:tuple :int] true}
(meta ^[:tuple :int] {})
; =throws=> Metadata must be Symbol,Keyword,String or Map
@ikitommi What do you expect the metadata to be?
{[:tuple :int] true}
?
yes, same as the second (working) example.
I believe shorthand syntax has been allocated parsimoniously as needed. So keyword shorthand was for opt-in flags and not a default transformation “if not a map or a type (sym/string) turn x in {x true}”.
Yes, the general case of metadata is always a map. The ^:kw
is just a light syntactic sugar that is replaced with a map {:kw true}
and only for keywords. (Well, there is also ^Classname
-> {:tag Classname}
)
ok, thanks. String also seems to write :tag
:
(meta ^int? {}) ; => {:tag #object[clojure.core$int_QMARK_"]}
(meta ^:int {}) ; => {:int true}
(meta ^"int" {}) ; => {:tag "int"}
(meta ^{:type :int} {}) ; => {:type :int}
(meta ^Integer {}) ; => {:tag java.lang.Integer}
I believe that's necessary to tag things when their class name is an invalid symbol, such as native arrays like
"[Ljava.lang.String;"
Yes it’s the reason.