Welcome! Please see the About page for a little more info on how this works.

0 votes
in Clojure by
retagged by

In larger code bases & teams, it is possible that different folks 'require' a namespace with a different alias

h.clj
(ns hello.core)

f.clj
(ns foo.core
    (:require [hello.core :as hc]))

b.clj
(ns bar.core
    (:require [hello.core :as h]))

If you see, big projects I have worked on often ends up having different aliases for the same namespace even though conventions are kept in place. This is a human flaw and in bigger teams this often goes out of track. This makes it harder to use simple tools like grep e.t.c to find usages of namespaces and functions within them (by doing say hc/some-func or h/some-func in the above case)

What I want to propose is in the ns macro itself have something like

(ns hello.core :default-alias <my-alias>)

and wherever this ns is require'd

(ns foo.core 
    (:require [hello.core :default-alias])

we automatically get a <my-alias> referencing the namespace so we can do <my-alias>/some-func

This would lead to a consistent code that will be enforced on language level
I believe this could be done using some sort of metadata stored in the namespace

2 Answers

+6 votes
by
selected by
 
Best answer

You can use the :consistent-alias linter in clj-kondo to enforce this kind of consistency:

https://github.com/borkdude/clj-kondo/blob/master/doc/config.md#alias-consistency

by
That's awesome! As a follow up, is it possible to have a user config for clj-kondo? Like say I'd want cross project defaults? Or establish a team wide convention?
by
A user config is not supported by design. You can read about it here in design principle 5: https://github.com/borkdude/clj-kondo/blob/master/doc/dev.md.
If this is important to you, I'd say just write a little templating script/lein template/clj new template that just copies your config.
+1 vote
by

Hi, thanks for the suggestion, it's one I haven't seen before.

I think one downside of this proposal is that aliases would appear "from nowhere" and that has its own kind of problems. I mean, that is kind of the point of course, but just looking at a particular consumer namespace, it would be impossible to know what an alias refers to without finding and resolving all of the other referenced namespaces.

In any case, we are not looking to add any additional complexity to the ns macro or namespace system, so I think it's unlikely we would add something like this.

by
Yeah, I feared the "from nowhere" concern too :)

Anyways, I'll try this myself at-least in my Clojure fork
by
Other problems with this:

If the source namespace changed the default alias for whatever reason, all the consuming code would break.

If two namespaces happened to have the same default alias, and you tried to require them both, you'd have a conflict.

Any tools that rely on statically checking code would not know what (hc/greet) was -- right now they see the :as hc alias and can "resolve" the hc/greet symbol without having to load the namespace.
...