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.