When to use aliases and when to use: refer to Clojure / ClojureScript: require?
When used :require
in Clojure or ClojureScript, when should you use aliases, and when should you only use the functions you use?
Examples:
-
Using a pseudonym
(:require [some-package.sub as some]) (some/do-stuff "xyz")
-
Using
:refer
(:require [some-package.sub :refer [do-stuff]]) (do-stuff "xyz")
Using an alias is more convenient if there are many functions in the dependency that you want to use, or if you use all of your functions (however many), especially since ClojureScript (intentionally) does not support :refer :all
. On the other hand, using :refer
it seems like a cleaner approach, especially when using only certain functions from a dependency.
Are there other things to consider when deciding between the two (and this is the real reason in the first place)?
Another thing I could think of is that if you have a lot of dependencies and / or loadings of your own functions defined in a file, it might be helpful to have alias prefixes in function calls to make them clearer, where these functions are found even if you only use a small subset of the functions offered by dependencies.
How do you choose which one to use? Or is it something you should just decide in your development team and it's okay if you stick with the same approach?
source to share
Using aliases allows you to immediately understand who is reading your code, where a particular variable is defined, especially when you standardize on the use of aliases throughout your project.
An unqualified name my-fn
can refer to:
- A var
my-fn
defined in the current namespace. - var
my-fn
, defined in some other namespace, flattened into the current namespace with:require :refer
- A local lexical binding (i.e. a function parameter or constraint-bound variable) with a name
my-fn
.
A qualified name a/my-fn
can only refer to:
- var
my-fn
in another namespace that it is aliased toa
(or namespacea
if you are naughty and use single-segment namespaces). - Less commonly, a static method or named field
my-fn
in a Java classa
.
The qualified name should not be confused for anything defined in the current namespace, and because you cannot use qualified names as function parameters or in bindings let
, there is no risk of it being shadowed by local lexical bindings. The use :require :refer
gives that clarity without giving you much in return and should be used sparingly in my opinion.
source to share
This is subjective, but I use aliases almost exclusively. The only exception is when I have a namespace that uses one or two functions from a different namespace to eliminate noise. For example, I usually refer deftest
from clojure.test
. However, I never name more than two functions.
Note that you can use :refer
both :as
together:
(ns my-ns
(:require [clojure.test :as test :refer [deftest]]))
source to share