【发布时间】:2018-04-28 19:23:08
【问题描述】:
TL;DR:以下是图书馆的好模式吗?
(def ^{:dynamic true} *var*)
(defn my-fn [{:keys [var]}]
(do-smth (or var *var*)))
--
假设我想写一个情感分析库。
在get-sentiment fn 中接受可选情感标签但提供默认情感标签作为动态变量是否是好的设计?
(def ^:dynamic *sentiment-level-labels*
["Very Negative" "Negative" "Neutral" "Positive" "Very Positive"])
;;...
(defn get-sentiment-scores
"Takes text and gives back a 0 to 4 sentiment score for each sentences."
[text]
;;...)
(defn get-sentiment
"Gives back a sentiment map with sentences scores,
average score, rounded score and labeled score.
Can accepts custom sentiment level labels under :labels opt."
[text & {:keys [labels]}]
(let [scores (get-sentiment-scores text)
average-score (get-average scores)
rounded-score (Math/round average-score)
label (get (or labels *sentiment-level-labels*) rounded-score)]
{:scores scores
:average-score average-score
:rounded-score rounded-score
:label label}))
Clojure 库编码标准官方页面说:
如果你提供一个隐式传递参数的接口 动态绑定(例如 sql 中的 db),也提供相同的接口 但是显式传递的参数。
https://dev.clojure.org/display/community/Library+Coding+Standards
在我的示例中,我只提供了一个接口,但带有 opt 参数。
这样好吗?有没有更好的方法来处理这个问题?
谢谢!
【问题讨论】:
-
根据我的经验,使用动态参数 /almost/ 总是比节省下来的麻烦更多。你需要一个非常有说服力的理由来拥有它们,在这种情况下,我肯定会让
*sentiment-level-labels*成为非动态的default-sentiment-level-labels。请注意,clojure.java.jdbc(如文档中的示例)曾经有一个动态的默认 db 参数,但它在很久以前就被删除了。 -
谢谢!我真的很喜欢“default-”前缀。
-
在不关闭耳罩的情况下
*sentiment-level-labels是否也可以直观地标记该值存在于函数中时未传入参数?甚至*default-sentiment-level-labels?谢谢! -
@leontalbot 不,那是超级恶心和奇怪的。没有人会那样使用
*,所以没有人阅读你的代码会理解你希望传达的意思。 -
Stuart Sierra 对动态变量进行了很好的讨论。它的标题是“动态范围的危险”。你也许能猜到他的结论是什么。 :-) 链接:stuartsierra.com/2013/03/29/perils-of-dynamic-scope
标签: clojure