Is there a way to create a named function in clojure that is visible only in the function area?

In Scheme, I can do something like this:

(define (adder)
  (define (one) 1)
  (define (two) 2)
  (+ (one) (two)))

A call adderleads to 3, and a call oneleads to an error, because it is onedisplayed only in the area adder.

In Clojure , if I do something like this

(defn adder []
  (defn one [] 1)
  (defn two [] 2)
  (+ (one) (two)))

oneand twowill pollute my namespace because it defnuses definternally, which creates bindings in the current namespace.

Is there a function / macro that creates named functions in a local scope?

The reason for my question is that I'm used to how the circuit works. Naming my local functions so often makes my code more readable.

+4
3

letfn:

. , .

 (defn adder []
   (letfn [(one [] 1)
           (two [] 2)]
     (+ (one) (two))))
+13

Alex, fn .

(defn adder []
  (let [one (fn [] 1)
        two (fn [] (+ (one) (one)))]
    (+ (one) (two))))

, let.

fn ,

(defn silly []
  (let [constant 5
        thing (fn thong
                ([a] (+ a constant))
                ([] (inc (thong constant))))]
    (* (thing) (thing))))

fn , .

+9

, , , defn -

defn -
  macro
  Usage: (defn-name and decls)
  is the same as defn, giving way to non-public def

from http://clojuredocs.org/clojure_core/clojure.core/defn-

user=> (ns test)
nil

test=> (defn- foo [] "World!")
#'test/foo

test=> (defn bar [] (str "Hello " (foo)))
#'test/bar

test=> (foo)
"World!"
test=> (bar)
"Hello World!"
test=> (ns playground)
nil
playground=> (test/bar)
"Hello World!"

;; Error will be thrown
;; var: #'test/foo is not public
playground=> (test/foo)
+1
source

Source: https://habr.com/ru/post/1534919/


All Articles