Both seem to denote a private function, similiar to that found in most OOP languages. Is there a functional difference or is one just syntactic sugar?
I've seen defn ^:private used in the context of the handler of a ring application.
In answer to the original question: there is no difference.
user=> (defn- a1 [b] b)
#'user/a1
user=> (defn ^:private a2 [b] b)
#'user/a2
user=> (meta #'a1)
{:private true, :arglists ([b]), :line 1, :column 1, :file "NO_SOURCE_PATH", :name a1, :ns #object[clojure.lang.Namespace 0xbaf1bb3 "user"]}
user=> (meta #'a2)
{:private true, :arglists ([b]), :line 1, :column 1, :file "NO_SOURCE_PATH", :name a2, :ns #object[clojure.lang.Namespace 0xbaf1bb3 "user"]}
user=> (source defn-)
(defmacro defn-
"same as defn, yielding non-public def"
{:added "1.0"}
[name & decls]
(list* `defn (with-meta name (assoc (meta name) :private true)) decls))
nil
user=>
As we can see from the source of defn-
it is functionally identically to defn
with :private true
metadata added to the name
symbol.
Regarding the macro
defn-
, it is just a shorthand for "private" functions. The long form looks like:However, this is just a hint to the user that one shouldn't use these functions. It is easy for testing, etc to work around this weak "private" restriction. Due to the hassle I never use so-called "private" functions (I do sometimes use metadata
^:no-doc
and names likefoo-impl
to indicate a fn is not a part of the public-facing API and should be ignored by library users).You can view the definition of
defn-
in the Clojure source code for more details.