有没有办法在clojure中创建一个只在函数范围内可见的命名函数?

Ada*_*old 4 scheme scope clojure

Scheme中,我可以这样做:

(define (adder)
  (define (one) 1)
  (define (two) 2)
  (+ (one) (two)))
Run Code Online (Sandbox Code Playgroud)

调用adder的结果3,同时呼吁one,因为会产生一个错误one是只的范围内可见adder.

Clojure,如果我做类似的事情

(defn adder []
  (defn one [] 1)
  (defn two [] 2)
  (+ (one) (two)))
Run Code Online (Sandbox Code Playgroud)

onetwo会污染我的命名空间,因为defn使用def内部这在当前的命名空间创建绑定.

是否有一个函数/宏在本地范围内创建命名函数?

我的问题的原因是我习惯了Scheme的工作方式.以这种方式命名我的本地函数通常会使我的代码更具可读性.

Ale*_*lex 13

试试letfn:

获取函数规范和正文的向量,并为其名称生成一组函数绑定.所有这些名称都可以在函数的所有定义以及正文中找到.

 (defn adder []
   (letfn [(one [] 1)
           (two [] 2)]
     (+ (one) (two))))
Run Code Online (Sandbox Code Playgroud)


noi*_*ith 9

除了亚历克斯的出色答案,任何fn可以命名.

(defn adder []
  (let [one (fn [] 1)
        two (fn [] (+ (one) (one)))]
    (+ (one) (two))))
Run Code Online (Sandbox Code Playgroud)

如果您已经有一个let块,这很有用.

如果一个fn引用它自己,它需要一个自己的名字

(defn silly []
  (let [constant 5
        thing (fn thong
                ([a] (+ a constant))
                ([] (inc (thong constant))))]
    (* (thing) (thing))))
Run Code Online (Sandbox Code Playgroud)

fn绑定的名称不必与它自己知道的名称相同.