您如何在Clojure特定语言或函数语言中实现一般的设计?

Rob*_*ell 7 scheme functional-programming design-by-contract clojure

我更喜欢使用Lisp变体(Clojure或Scheme的奖励积分)的例子,因为这是我最熟悉的,但任何有关DBC功能性语言的反馈当然对更大的社区都有价值.

这是一个显而易见的方式:

(defn foo [action options]
    (when-not (#{"go-forward" "go-backward" "turn-right" "turn-left"} action)
              (throw (IllegalArgumentException.
                     "unknown action")))
    (when-not (and (:speed options) (> (:speed options) 0))
              (throw (IllegalArgumentException.
                     "invalid speed")))
    ; finally we get to the meat of the logic)
Run Code Online (Sandbox Code Playgroud)

我不喜欢这个实现的是合同逻辑掩盖了核心功能; 在条件检查中,函数的真正目的会丢失.这与我在这个问题中提出的问题相同.在像Java这样的命令式语言中,我可以使用嵌入在文档中的注释或元数据/属性来将契约移出方法实现.

有没有人考虑在Clojure中添加合同到元数据?如何使用高阶函数?还有哪些其他选择?

dno*_*len 4

Clojure 已经支持前置条件和后置条件,遗憾的是没有详细记录:

我应该使用函数还是宏来验证 Clojure 中的参数?