9

作为一个附带项目,我正在创建一个用于图像合成 ( clisk ) 的 Clojure DSL。

我有点不确定函数命名的最佳方法,其中我在 DSL 中的函数类似于 Clojure 核心中的函数,例如+,我的 DSL 中需要函数或类似的东西来附加地组合图像/执行矢量数学运算.

据我所知,有几个选择:

  1. +在我自己的命名空间中使用相同的名称 ( )。在 DSL 代码中看起来不错,但会覆盖 clojure.core 版本,这可能会导致问题。人们可能会感到困惑。
  2. 使用相同的名称,但需要对其进行限定 ( my-ns/+)。避免冲突,但use为了方便起见阻止人们访问命名空间,看起来有点难看。
  3. 使用不同的短名称,例如 ( v+)。可以很use容易地避免冲突,但这个名字有点难看,可能很难记住。
  4. 使用不同的长名称,例如 ( vector-add)。详细但具有描述性,没有冲突。
  5. 使用多方法排除clojure.core/+和重新定义+(如 georgek 建议的那样)。

示例代码可能类似于:

 (show  (v+ [0.9 0.6 0.3] 
             (dot [0.2 0.2 0] 
                  (vgradient (vseamless 1.0 plasma) ))))

最好/最惯用的方法是什么?

4

1 回答 1

4

首先,运算符在中缀表达式中的重复出现需要良好的语法,但对于带有前缀语法的 lisp,我认为这并不重要。因此,让用户为显式命名空间键入更多字符并不是犯罪。并且 clojure 对命名空间和别名有很好的支持。因此用户很容易选择自己的短前缀:(x/+ ...)例如。

其次,查看阅读器文档,没有太多可以使用的非字母数字符号,所以类似的东西:+已经出来了。所以没有“可爱”的解决方案——如果你选择一个前缀,它必须是一个字母。这意味着类似x+- 最好让用户选择一个别名,以多一个字符为代价,并拥有x/+.

所以我会说:忽略核心,但期望用户(:require .... :as ...)。如果他们非常喜欢你的包,他们希望它是默认的,那么他们可以(:use ...)明确地处理核心。但是您为运算符选择前缀似乎是一个糟糕的妥协。

(而且我认为我没有看到任何使用单字母前缀的库)。

另一种可能性是提供上述内容以及具有长名称而不是运算符的单独包(它们只是简单地定义以匹配原始包中的值)。那么如果人们确实想要(:use ...)但想要避免冲突,他们可以使用它(但实际上(vector-add ...)over的优势是(vector/+ ...)什么?)

and finally i would check how + is implemented, since if it already involves some kind of dispatch on types then georgek's comment makes a lot of sense.

(by "operator" above i just mean single-character, non-alphanumeric symbol)

于 2012-07-23T17:49:50.240 回答