Namespaced keys are awesome. As many others, I’ve found that using keys/attributes/fields/etc. which name uniquely identify one type of information without any more context needed is a very efficient strategy to make programs that are clearer and more regular all across the stack.
What I’m questioning here is the use of Clojure’s syntax/convention for namespacing keys, i.e the use of dots .
and slashes /
, e.g :org.foo.user/first-name
instead of say org_foo_user_first_name
.
Clojure’s convention is arguably more visually pleasing, but it can get unwieldly or even impossible to use outside of Clojure code, e.g in a JavaScript client, as PostgreSQL column names, in an ElasticSearch index… which seems to defeat the purpose of namespaced keywords, which is to make the flow of information straightforwardly to follow in a very pervasive way (more pervasive than a type system for instance). This seems to go against an excellent piece of advice I heard from Stuart Halloway: don’t put your language semantics over the wire.
One can imagine several strategies to mitigate this problem:
-
Ditch the namespace part outside of Clojure code, e.g
:org.foo.user/id -> "id"
. - Have some form of systematic translation from one namespacing convention to another, e.g
:org.foo.user/first-name -> orgFooUser_firstName
- Stop using Clojure’s namespacing convention for keys that will travel outside of your Clojure app’s boundaries - which is probably most keys representing information.
Approach 1 is what I first tried when building BandSquare, and I really regretted it - I think it eliminates many benefits of namespacing keys. Approach 2 seems hacky at best, and you get much less leverage from your tooling. So I’m starting to think approach 3 is the sanest default.
This question is even more important now that Spec exists, because Spec encourages Clojure’s syntax for keywords and associates specific semantics to it.
What do you think?