defn
= public defn-
= private 也许我的Clojure编码风格很糟糕 - 但我发现我在Clojure中编写的大多数函数都是小助手函数,我不想公开。
是否有一些配置选项,其中:
defn
=默认为私有,defn+
?谢谢!
答案 0 :(得分:17)
没有。没有。
可能或可能不适合您的替代方法是声明一个foo.bar.internal
命名空间,其中包含foo.bar
命名空间使用的所有私有帮助程序。当你想在宏扩展中使用私有函数时,这比私有函数声明更有优势。
答案 1 :(得分:5)
正如@kotarak所说,没有办法(据我所知)这样做,也不可取。
这就是为什么我不喜欢defn-
:
我发现当使用各种Clojure库时,我有时需要稍微修改一个函数以更好地满足我的特定需求。 它通常很小,只有在我的特定情况下才有意义。通常这只是一两个字符。
但是当这个函数重用内部私有函数时,它会使修改变得更加困难。我必须复制粘贴所有这些私有函数。
我理解这是程序员说的一种方式,这可能会在没有通知的情况下发生变化"。
无论如何,我想要相反的惯例:
defn
,这会使所有内容公开defn+
(尚不存在)向程序员指定哪些函数是他应该使用的公共API的一部分。 defn+
应该与defn
无异。另请注意,无论如何都可以access private functions:
;; in namespace user
user> (defn- secret []
"TOP SECRET")
;; from another namespace
(#'user/secret) ;;=> "TOP SECRET"
答案 2 :(得分:5)
Clojure作为Lisp的美妙之处在于,您可以构建和调整语言以满足您的需求。我强烈建议您阅读On Lisp, by Paul Graham。他现在免费赠送他的书。
关于你对defn + vs defn vs defn-的建议。这听起来像是写一个自己宏的好例子。 defn
是一个函数,defn-
是一个宏。您可以根据需要重新定义它们,或者将它们包装在您自己的中。
以下是对实现的建议,主要基于Clojure自己的实现 - 包括一个简单的实用程序和一个测试。
(defmacro defn+
"same as Clojure's defn, yielding public def"
[name & decls]
(list* `defn (with-meta name (assoc (meta name) :public true)) decls))
(defmacro defn
"same as Clojure's defn-, yielding non-public def"
[name & decls]
(list* `defn (with-meta name (assoc (meta name) :private true)) decls))
(defn mac1
"same as `macroexpand-1`"
[form]
(. clojure.lang.Compiler (macroexpand1 form)))
(let [ ex1 (mac1 '(defn f1 [] (println "Hello me.")))
ex2 (mac1 '(defn+ f2 [] (println "Hello World!"))) ]
(defn f1 [] (println "Hello me."))
(defn+ f2 [] (println "Hello World!"))
(prn ex1) (prn (meta #'f1)) (f1)
(prn ex2) (prn (meta #'f2)) (f2) )
答案 3 :(得分:4)
如果“辅助函数”很可能只使用一次,您可以选择将它们作为较大函数的本地函数,或者将它们写为匿名函数。请参阅letfn
:http://clojuredocs.org/clojure_core/clojure.core/letfn和http://clojuredocs.org/clojure_core/clojure.core/fn。
我自己几乎不用letfn
。