mik*_*era 9 dsl namespaces clojure
作为一个侧面项目,我正在创建一个用于图像合成的Clojure DSL(clisk).
我对函数命名的最佳方法有些不确定,其中我在DSL中具有与Clojure核心中的+函数类似的函数,例如我的DSL中需要函数或类似的东西以附加地组合图像/执行矢量数学运算.
据我所知,有几个选择:
+在我自己的命名空间中使用相同的名称().在DSL代码中看起来不错,但会覆盖clojure.core版本,这可能会导致问题.人们可能会感到困惑.my-ns/+).避免冲突,但use为了方便而阻止人们进入命名空间并且看起来有点难看.v+).可以很use容易地避免冲突,但名字有点难看,可能难以记住.vector-add).冗长但描述性,没有冲突.clojure.core/+和重新定义+(正如乔治克所建议的那样).示例代码可能类似于:
(show (v+ [0.9 0.6 0.3]
(dot [0.2 0.2 0]
(vgradient (vseamless 1.0 plasma) ))))
Run Code Online (Sandbox Code Playgroud)
什么是最好/最惯用的方法?
首先,中缀表达式中运算符的重复出现需要良好的语法,但对于带有前缀语法的 lisp 来说,我认为这并不那么重要。因此,让用户为显式命名空间输入更多字符并不是什么犯罪行为。并且 clojure 对命名空间和别名有很好的支持。因此用户可以很容易地选择自己的短前缀:(x/+ ...)例如。
其次,查看阅读器文档,没有很多非字母数字符号可供使用,因此类似的东西:+已经消失了。所以没有“可爱”的解决方案 - 如果你选择一个前缀,它必须是一个字母。这意味着类似x+- 更好地让用户选择一个别名,以多一个字符为代价,并拥有x/+.
所以我会说:忽略核心,但期望用户(:require .... :as ...)。如果他们非常喜欢你的包,他们希望它成为默认的,那么他们可以(:use ...)明确地处理核心。但是您选择运算符的前缀似乎是一个糟糕的妥协。
(而且我认为我没有见过任何使用单字母前缀的库)。
另一种可能性是提供上述内容以及一个具有长名称而不是运算符的单独包(它们只是简单地定义以匹配原始包中的值)。那么如果人们确实想要(:use ...)但又想避免冲突,他们可以使用它(但实际上这样做的好处是什么(vector-add ...)?(vector/+ ...))
最后我会检查如何+实现,因为如果它已经涉及某种类型的调度,那么 georgek 的评论就很有意义。
(上面的“运算符”只是指单字符、非字母数字符号)