Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do we need ' in (require '[...]]) with Clojure?

Tags:

clojure

I see that we don't need ' with (ns ...) as ns is a macro. However, why do we need ' in (require '[...])? I thought that Clojure's vector is a fancy way to avoid ', but now I see one here.

We use (require 'clojure.string) so require seems to be a function, but we don't quote a vector when given as a parameter.

enter image description here

The error message from not quoting is also confusing.

like image 253
prosseek Avatar asked Nov 07 '15 02:11

prosseek


2 Answers

This is because require is implemented as a function and not a macro, hence it needs a quoted libspec. An unquoted libspec would be evaluated like this:

user=> [clojure.set :as s]
CompilerException java.lang.ClassNotFoundException: clojure.set

thus yielding an error.

However, ns is implemented as a macro and has full control over if or when to evaluate its arguments any further, so you don't need to quote the libspec. You can look at a macroexpansion of ns and see what happens when it is expanded:

user=> (use 'clojure.pprint)
nil
user=> (pprint (macroexpand '(ns foo (:require [clojure.set :as s]))))
(do
 (clojure.core/in-ns 'foo)
 (clojure.core/with-loading-context
  (clojure.core/refer 'clojure.core)
  (clojure.core/require '[clojure.set :as s]))
 (if
  (.equals 'foo 'clojure.core)
  nil
  (do
   (clojure.core/dosync
    (clojure.core/commute
     @#'clojure.core/*loaded-libs*
     clojure.core/conj
     'foo))
   nil)))
nil

As you can see, ns just takes the libspec as it is and quotes it for you before passing it to require, so you don't have to.

like image 56
Michiel Borkent Avatar answered Oct 13 '22 17:10

Michiel Borkent


The niche is: Quoting a vector is essentially quoting every sub-forms inside the vector form.

user> (= '[a b c] ['a 'b 'c])
=> true

The require form can take either a quoted symbol, referencing a namespace, or it can take a vector of quoted symbols putting further restrictions.

like image 5
Davyzhu Avatar answered Oct 13 '22 17:10

Davyzhu