NB: this feature is included in core Clojure as of 1.11.0-alpha2, see CLJ-2123 and require’s :as-alias.
I like to namespace my keys, and I like to use aliases too. Some of these namespaces don’t have files associated with them, but this get tiresome and looks ugly.
(create-ns 'ae.concise.brevity.foo)
(alias 'foo 'ae.concise.brevity.foo)
(create-ns 'ae.concise.brevity.bar)
(alias 'bar 'ae.concise.brevity.bar)
(create-ns 'ae.concise.brevity.qux)
(alias 'qux 'ae.concise.brevity.qux)
{::foo/options ::bar/default
::foo/connection ::qux/client}alias+ns combines the creation and aliasing into a single line.
(alias+ns 'foo 'ae.concise.brevity.foo)
(alias+ns 'bar 'ae.concise.brevity.bar)
(alias+ns 'qux 'ae.concise.brevity.qux)
{::foo/options ::bar/default
::foo/connection ::qux/client}And aliases+ns combines all that into a single sexp.
(aliases+ns {'foo 'ae.concise.brevity.foo
'bar 'ae.concise.brevity.bar
'qux 'ae.concise.brevity.qux})
{::foo/options ::bar/default
::foo/connection ::qux/client}Add the library to your deps.edn:
{:deps {ae/alias+ns {:git/url "https://github.com/EducatedAlmost/alias-ns"
:git/sha "..."}}}The order of arguments is [alias namespace], following the example of clojure.core/alias. aliases+ns takes a map of alias–namespace pairs.
(require '[ae.alias+ns :as ns])
;; Define a single alias
(ns/alias+ns 'foo 'ae.concise.brevity.foo)
{::foo/baz :qux}
;; ==> {:ae.concise.brevity.foo/baz :qux}
;; Define multiple aliases at once
(ns/aliases+ns {'a 'ae.concise.brevity.a
'b 'ae.concise.brevity.b
'c 'ae.concise.brevity.c})
{::a/qux true
::b/qux false
::c/qux nil}
;; ==> {:ae.concise.brevity.a/qux true
;; :ae.concise.brevity.b/qux false
;; :ae.concise.brevity.c/qux nil}clj-kondo thankfully warns one when one uses an alias that doesn’t exist. Unfortunately it is unwelcome when that alias has actually been created by alias+ns. One can instruct clj-kondo to treat alias+ns as it does alias by adding it to its configuration:
{:lint-as {ae.alias+ns/alias+ns clojure.core/alias}}If using aliases+ns this won’t work and one can either use (macroexpand-1 '(aliases+ns {...})) to expand into multiple calls to alias+ns, or disable the linter entirely:
{:linters {:unresolved-namespace {:level :off}}For more information on clj-kondo and its configuration, see its documentation.
Probably maybe. I have written this, and only used it, in writing wrappers for libraries written in other languages which generally have more complicated structures and hierarchies than one would expect in Clojure. Instead of devising a novel naming system, I would rather use one that closely mirrors the original library to reduce the cognitive load of remembering two systems, and to allow consumers of my library to use the original library’s documentation as a reference.