A common usage of namespaced keywords and symbols is in providing attribute disambiguation in map contexts:
{:person/first "Han" :person/last "Solo" :person/ship {:ship/name "Millenium Falcon" :ship/model "YT-1300f light freighter"}}
The namespaces provide value (disambiguation) but have the downside of being repetitive and verbose.
Namespaced maps are a reader (and printer) feature to specify a namespace context for a map.
Examples:
;; same as above - notice you can nest #: maps and this is a case where the printer roundtrips user=> #:person{:first "Han" :last "Solo" :ship #:ship{:name "Millenium Falcon" :model "YT-1300f light freighter"}} #:person{:first "Han" :last "Solo" :ship #:ship{:name "Millenium Falcon" :model "YT-1300f light freighter"}} ;; effects on keywords with ns, without ns, with _ ns, and non-kw user=> #:foo{:kw 1, :n/kw 2, :_/bare 3, 0 4} {:foo/kw 1, :n/kw 2, :bare 3, 0 4} ;; auto-resolved namespaces (will use user as the ns) user=> #::{:kw 1, :n/kw 2, :_/bare 3, 0 4} :user/kw 1, :n/kw 2, :bare 3, 0 4} ;; auto-resolve alias s to clojure.string user=> (require '[clojure.string :as s]) nil user=> #::s{:kw 1, :n/kw 2, :_/bare 3, 0 4} {:clojure.string/kw 1, :n/kw 2, :bare 3, 0 4} ;; to show symbol changes, we'll quote the whole thing to avoid evaluation user=> '#::{a 1, n/b 2, _/c 3} {user/a 1, n/b 2, c 3} ;; edn reader also supports (only) the #: syntax user=> (clojure.edn/read-string "#:person{:first \"Han\" :last \"Solo\" :ship #:ship{:name \"Millenium Falcon\" :model \"YT-1300f light freighter\"}}") #:person{:first "Han", :last "Solo", :ship #:ship{:name "Millenium Falcon", :model "YT-1300f light freighter"}}
Open questions:
1. Current patch does not allow whitespace between ns and map definition. Should we allow whitespace there for formatting?
2. Should autoresolution support fully-qualified loaded namespaces? (like auto-resolved keywords)
3. Should there be a printer flag to suppress printing namespaced maps?
4. Patch changes print-method for maps but not pprint. Should it?
Could you say more about the issue? Is it a problem of human readability?
Thanks Mike, that's a compelling example.
Ambrose
This is a bit prior to the proposal, but I would appreciate an explanation of the benefits of namespace keywords in different scenarios. The canonical usage in my mind is for adding keys to maps whose contents you don't fully control (like metadata on vars, ring middleware that adds keys to a request map, etc.). I'm less clear on the benefits for data that the user has more direct control over: e.g., when Mike says "it's clearly worth it", I have no idea what sort of benefits he has in mind.
I think the proposal overall is great but I agree that assigning special meaning to _ in this context seems like the wrong thing to do. Since that seems present only to support literals that are a mix of namespaced keywords and bare keywords – can you (Rich, or Alex?) explain the use case that makes it worthwhile to have these bare keywords in the same map?
To kick in a real world example, we use namespaced keywords everywhere in Onyx. It's clearly worth it, so we continue to do it - but man it can be a pain: https://github.com/onyx-platform/onyx/blob/0.9.x/src/onyx/peer/function.clj#L20-L21
On 8 April 2016 at 16:43, Mike Drogalis <madru...@gmail.com> wrote:
Note that if onyx.core is an actual Clojure namespace, you could save
some typing on the lines you highlighted:
{:keys [onyx.core/results onyx.core/messenger onyx.core/state
onyx.core/replica onyx.core/peer-replica-view
onyx.core/serialized-task] :as event}
by requiring [onyx.core :as c] (for example) and then saying (note the
double colon)
::c/results ::c/messenger ::c/state …
--
#:person{::first "John" ::last "Doe" :id 10}
;=> {:person/first "John" :person/last "Doe" :id 10}
#:[{_ person d db} {::first "first" ::d/id 10}]
;=> {:person/first :db/id 10}
Pros
- The double colon without namespace part is currently illegal. Now it is legal only inside these namespaced maps.
This new syntax is similar in a way to syntax-quote. Have youconsidered making it more outwardly similar and providing a similarunquote mechanism?