clojure-dev

Issues: https://clojure.atlassian.net/browse/CLJ | Guide: https://insideclojure.org/2015/05/01/contributing-clojure/
ikitommi 2021-03-14T12:44:56.073200Z

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

borkdude 2021-03-14T12:49:31.075400Z

@ikitommi What do you expect the metadata to be?

borkdude 2021-03-14T12:49:43.075700Z

{[:tuple :int] true} ?

ikitommi 2021-03-14T12:50:02.076200Z

yes, same as the second (working) example.

cgrand 2021-03-14T13:12:45.080800Z

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}”.

2021-03-14T13:50:24.081400Z

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})

ikitommi 2021-03-14T14:55:10.082600Z

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}

2021-03-14T15:12:14.082800Z

I believe that's necessary to tag things when their class name is an invalid symbol, such as native arrays like

"[Ljava.lang.String;"

cgrand 2021-03-14T15:22:02.083200Z

Yes it’s the reason.

alexmiller 2021-03-14T22:12:57.083500Z

https://clojure.org/reference/reader#_metadata

👍 1