Should we really use Clojure's syntax for namespaced keys?

Hey @vvvvalvalval,

That’s an interesting problem. I’ve encountered it in specific circumstances and found workarounds, but never had to address it generally. These are just some random thoughts.

One solution I’ve used is to just use fully qualified keywords as strings (pr-str them and drop the “:”) for JSON keys and Postgres column names. In Postgres, you have to use the quoted identifier, which allows anything except the null character. Then you can output them and read them back in with a simple call to keyword. This should also work generally with languages that use hashmaps.

I’m not a fan of #1. There are too many collisions.

For approach #2, this is how Clojure manages to use hyphens, question marks, and bangs in symbol names, yet still use those to generate valid Java classnames. There’s a function called clojure.core/munge that does this systematically. It’s a one-way function, though, which suits the Clojure compiler’s purpose.

There could be something like munge, with similar conventions. One you might try is to use convert . to _ in the namespace, and - to _ in the name. The / could become __ (double underscore).

It’s not perfect, but it corresponds to other conventions I’ve seen. The real issues are what to do with hyphens in the namespace and dots in the name. They’re less common, but that would only make the times they do occur harder to debug.

A hybrid with #3 is probably the sanest. There’s no reason the namespaces of Clojure keywords need to correspond to Clojure’s lib namespaces (typical code files with an ns declaration at the top). I think with the profusion of Spec examples that use the :: syntax, we often get confused about that. :: is just a lazy way of adding a namespace. We should be thinking more about what the public, global, permanent name of a thing should be than whatever file it happens to be in when we write the code.

So, there’s no reason you can’t do this as a namespaced key:

org_clojureverse_user__first_name, which converts to :org_clojureverse_user/first_name.

That said, I’d carefully evaluate the systems that will need to use these names. I’d rather use JavaScript’s object["org.clojureverse.user/first-name"] syntax than have to come up with a translation system that can go both ways. It’s not like object.org_clojureverse_user__first_name is any less ugly :slight_smile:

Eric

3 Likes