openlang

Does Clojure make defn- distinct from declaring a function with ^:private?

Each appears to declare a private function, as in most object-oriented languages. Do they behave differently, or does one merely provide syntactic sugur?

I've encountered defn ^:private in code defining a ring application's handler function.

The conversation continues 2

Follow the reasoning
  1. Permalink

    The defn- macro simply abbreviates a "private" function declaration. Written out fully, it becomes:

    
    (defn ^:private entry [inputs] ...)

    This is really only a signal to users to avoid those functions. Bypassing this limited "private" protection for testing and similar tasks is straightforward. I avoid so-called "private" functions because of the inconvenience (occasionally I attach ^:no-doc metadata and choose names such as entry-impl to show a fn isn't within the public API and library consumers ought to disregard it).

    For additional details, inspect how Clojure source code defines defn- (https://github.com/clojure/clojure/blob/38bafca9e76cd6625d8dce5fb6d16b87845c8b9d/src/clj/clojure/core.clj#L4925).

  2. Permalink

    To address what was asked originally: they are equivalent.

    
    user=> (defn- first_fn [value] value)
    #'user/first_fn
    user=> (defn ^:private second_fn [value] value)
    #'user/second_fn
    user=> (meta #'first_fn)
    {:private true, :arglists ([value]), :line 1, :column 1, :file "NO_SOURCE_PATH", :name first_fn, :ns #object[clojure.lang.Namespace 0xcaf2cc4 "user"]}
    user=> (meta #'second_fn)
    {:private true, :arglists ([value]), :line 1, :column 1, :file "NO_SOURCE_PATH", :name second_fn, :ns #object[clojure.lang.Namespace 0xcaf2cc4 "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=>

    Examining the implementation of defn- shows it behaves exactly like defn after attaching :private true metadata to the name symbol.

Other sides of the same question

  1. Choosing enum entries randomly with GDScript in Godot 3.3 without listing each one?

    Here's the enum declaration I'm using in GDScript: I'd like to choose an enum variant randomly without listing every possible…

    Replies 2Latest activity gdscript
  2. Nim remainder syntax

    How is modulus expressed in Nim? cell % 7 == 0 gives undeclared identifier: '%' Neither a Google search nor looking through S…

    Replies 2Latest activity nim
  3. Returning results from an APL function

    How do I make my function return something once execution has finished? For instance, I have: ROUTINE N ? N ⍴ 12 //That gener…

    Replies 2Latest activity apl