Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

clojure - :refer vs :as

I'm learning clojure. As part of the :require process, there is an option to use :refer for a specific method or all the methods.

Or to use the :as and then to choose the method you need.

I think I understand the difference between the 2 options, and also seen the documentation here that says:

:as takes a symbol as its argument and makes that symbol an alias to the lib's namespace in the current namespace.

:refer takes a list of symbols to refer from the namespace or the :all keyword to bring in all public vars.

But I'm still not sure about:

  1. When should I use one option and not the other?

  2. Is there a performance difference between the two options? (My thoughts say that there is non since the compilar will optimize both options

(I also did 2 small programs that uses core.asyc, one uses :as and one uses :refer. The time it took to run both was pretty much the same.

like image 804
boaz Avatar asked Sep 12 '19 19:09

boaz


1 Answers

I pretty much always use :as like this:

(ns demo.core
  (:require
    [clojure.string :as str] ))

(println (str/join ["hello" "there"]))

This allows the reader to see that join belongs to str (a namespace alias), and they can easily see that join resolves to clojure.string/join.

Consider the alternate:

(ns demo.core
  (:require
    [clojure.string :refer [join] ))

<snip>
...397 lines of other code...
</snip>

(println (join ["hello" "there"]))

Here join looks like a local function defined in demo.core, and it can take a while for the reader to figure out where it comes from. They can still trace down the origin by looking in the ns declaration, but unless it is a very common function, most people agree that the namespace alias technique is easier/faster to grok when reading code you didn't write.


In execution, the compiler will convert both forms to the same machine code, so there is no difference there.

like image 138
Alan Thompson Avatar answered Oct 06 '22 17:10

Alan Thompson